由于创建和关闭线程比较耗资源耗时,所以使用线程池,在应用启动时候,就创建多个线程,减少用户请求时创建和关闭线程的时间;而且使用完毕,线程不关闭,可以重复使用,提高并发性能
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:security="http://www.springframework.org/schema/security" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <!-- 配置线程池 --> <bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"> <!-- 核心线程数,默认为1 --> <property name="corePoolSize" value="5" /> <!-- 最大线程数,默认为Integer.MAX_VALUE --> <property name="maxPoolSize" value="50" /> <!-- 队列最大长度,一般需要设置值>=notifyScheduledMainExecutor.maxNum;默认为Integer.MAX_VALUE --> <property name="queueCapacity" value="1000" /> <!-- 线程池维护线程所允许的空闲时间,默认为60s --> <property name="keepAliveSeconds" value="300" /> <!-- 线程池对拒绝任务(无线程可用)的处理策略,目前只支持AbortPolicy、CallerRunsPolicy;默认为后者 --> <property name="rejectedExecutionHandler"> <!-- AbortPolicy:直接抛出java.util.concurrent.RejectedExecutionException异常 --> <!-- CallerRunsPolicy:主线程直接执行该任务,执行完之后尝试添加下一个任务到线程池中,可以有效降低向线程池内添加任务的速度 --> <!-- DiscardOldestPolicy:抛弃旧的任务、暂不支持;会导致被丢弃的任务无法再次被执行 --> <!-- DiscardPolicy:抛弃当前任务、暂不支持;会导致被丢弃的任务无法再次被执行 --> <bean class="java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy" /> </property> </bean> </beans>
package com.gxx.record.web.thread; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.task.TaskExecutor; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import com.gxx.record.thread.TestThread; /** * RedisController * * @author gxx */ @Controller @RequestMapping("/thread/") public class ThreadController { /** * 日志处理器 */ private final Logger logger = Logger.getLogger(ThreadController.class); @Autowired private TaskExecutor taskExecutor; /** * 执行线程 * @param request * @return */ @RequestMapping(value = "/execute",produces="application/json") public @ResponseBody String execute() { logger.info("执行线程,开始==="); for(int i=0;i<20;i++){ taskExecutor.execute(new TestThread()); } logger.info("执行线程,结束==="); return "执行线程OK~"; } }
package com.gxx.record.thread; import org.apache.log4j.Logger; /** * <dl> * <dt><b>Title:</b></dt> * <dd> * none * </dd> * <dt><b>Description:测试线程</b></dt> * <dd> * <p>none * </dd> * </dl> * * @author Administrator * @version 1.0, 2016年1月12日 * @since record * */ public class TestThread implements Runnable { /** * 日志处理器 */ private final Logger logger = Logger.getLogger(TestThread.class); @Override public void run() { double random = Math.random(); logger.info("线程[" + random + "]开始===="); try { Thread.sleep(5000); } catch (InterruptedException e) { logger.error("异常发生", e); } logger.info("线程[" + random + "]结束===="); } }
[Protocol]://[IP]:[Port]/record/thread/execute.htm
2016-01-12 17:32:47,500 [http-80-exec-3] INFO [com.gxx.record.web.thread.ThreadController:35] - 执行线程,开始=== 2016-01-12 17:32:47,536 [taskExecutor-1] INFO [com.gxx.record.thread.TestThread:31] - 线程[0.7581638006104884]开始==== 2016-01-12 17:32:47,542 [taskExecutor-2] INFO [com.gxx.record.thread.TestThread:31] - 线程[0.26717497775717225]开始==== 2016-01-12 17:32:47,544 [http-80-exec-3] INFO [com.gxx.record.web.thread.ThreadController:39] - 执行线程,结束=== 2016-01-12 17:32:47,551 [taskExecutor-3] INFO [com.gxx.record.thread.TestThread:31] - 线程[0.2286343802659081]开始==== 2016-01-12 17:32:47,551 [taskExecutor-4] INFO [com.gxx.record.thread.TestThread:31] - 线程[0.40159528085293983]开始==== 2016-01-12 17:32:47,551 [taskExecutor-5] INFO [com.gxx.record.thread.TestThread:31] - 线程[0.7048063013994695]开始==== 2016-01-12 17:32:52,537 [taskExecutor-1] INFO [com.gxx.record.thread.TestThread:37] - 线程[0.7581638006104884]结束==== 2016-01-12 17:32:52,537 [taskExecutor-1] INFO [com.gxx.record.thread.TestThread:31] - 线程[0.059500105635519995]开始==== 2016-01-12 17:32:52,543 [taskExecutor-2] INFO [com.gxx.record.thread.TestThread:37] - 线程[0.26717497775717225]结束==== 2016-01-12 17:32:52,543 [taskExecutor-2] INFO [com.gxx.record.thread.TestThread:31] - 线程[0.11292183552137725]开始==== 2016-01-12 17:32:52,552 [taskExecutor-5] INFO [com.gxx.record.thread.TestThread:37] - 线程[0.7048063013994695]结束==== 2016-01-12 17:32:52,552 [taskExecutor-3] INFO [com.gxx.record.thread.TestThread:37] - 线程[0.2286343802659081]结束==== 2016-01-12 17:32:52,552 [taskExecutor-4] INFO [com.gxx.record.thread.TestThread:37] - 线程[0.40159528085293983]结束==== 2016-01-12 17:32:52,552 [taskExecutor-4] INFO [com.gxx.record.thread.TestThread:31] - 线程[0.7358251609451018]开始==== 2016-01-12 17:32:52,552 [taskExecutor-5] INFO [com.gxx.record.thread.TestThread:31] - 线程[0.1580951886133759]开始==== 2016-01-12 17:32:52,552 [taskExecutor-3] INFO [com.gxx.record.thread.TestThread:31] - 线程[0.52309011015079]开始==== 2016-01-12 17:32:57,537 [taskExecutor-1] INFO [com.gxx.record.thread.TestThread:37] - 线程[0.059500105635519995]结束==== 2016-01-12 17:32:57,537 [taskExecutor-1] INFO [com.gxx.record.thread.TestThread:31] - 线程[0.7715091558058593]开始==== 2016-01-12 17:32:57,543 [taskExecutor-2] INFO [com.gxx.record.thread.TestThread:37] - 线程[0.11292183552137725]结束==== 2016-01-12 17:32:57,543 [taskExecutor-2] INFO [com.gxx.record.thread.TestThread:31] - 线程[0.4012926228584127]开始==== 2016-01-12 17:32:57,552 [taskExecutor-5] INFO [com.gxx.record.thread.TestThread:37] - 线程[0.1580951886133759]结束==== 2016-01-12 17:32:57,552 [taskExecutor-4] INFO [com.gxx.record.thread.TestThread:37] - 线程[0.7358251609451018]结束==== 2016-01-12 17:32:57,552 [taskExecutor-5] INFO [com.gxx.record.thread.TestThread:31] - 线程[0.01744115803065438]开始==== 2016-01-12 17:32:57,552 [taskExecutor-4] INFO [com.gxx.record.thread.TestThread:31] - 线程[0.24932939144870025]开始==== 2016-01-12 17:32:57,553 [taskExecutor-3] INFO [com.gxx.record.thread.TestThread:37] - 线程[0.52309011015079]结束==== 2016-01-12 17:32:57,553 [taskExecutor-3] INFO [com.gxx.record.thread.TestThread:31] - 线程[0.04881832451589985]开始==== 2016-01-12 17:33:02,538 [taskExecutor-1] INFO [com.gxx.record.thread.TestThread:37] - 线程[0.7715091558058593]结束==== 2016-01-12 17:33:02,539 [taskExecutor-1] INFO [com.gxx.record.thread.TestThread:31] - 线程[0.4083415424974973]开始==== 2016-01-12 17:33:02,544 [taskExecutor-2] INFO [com.gxx.record.thread.TestThread:37] - 线程[0.4012926228584127]结束==== 2016-01-12 17:33:02,544 [taskExecutor-2] INFO [com.gxx.record.thread.TestThread:31] - 线程[0.2364869187222809]开始==== 2016-01-12 17:33:02,553 [taskExecutor-5] INFO [com.gxx.record.thread.TestThread:37] - 线程[0.01744115803065438]结束==== 2016-01-12 17:33:02,553 [taskExecutor-4] INFO [com.gxx.record.thread.TestThread:37] - 线程[0.24932939144870025]结束==== 2016-01-12 17:33:02,553 [taskExecutor-5] INFO [com.gxx.record.thread.TestThread:31] - 线程[0.4265823186451243]开始==== 2016-01-12 17:33:02,553 [taskExecutor-4] INFO [com.gxx.record.thread.TestThread:31] - 线程[0.1992069353563678]开始==== 2016-01-12 17:33:02,554 [taskExecutor-3] INFO [com.gxx.record.thread.TestThread:37] - 线程[0.04881832451589985]结束==== 2016-01-12 17:33:02,554 [taskExecutor-3] INFO [com.gxx.record.thread.TestThread:31] - 线程[0.5413294134596947]开始==== 2016-01-12 17:33:07,539 [taskExecutor-1] INFO [com.gxx.record.thread.TestThread:37] - 线程[0.4083415424974973]结束==== 2016-01-12 17:33:07,544 [taskExecutor-2] INFO [com.gxx.record.thread.TestThread:37] - 线程[0.2364869187222809]结束==== 2016-01-12 17:33:07,553 [taskExecutor-5] INFO [com.gxx.record.thread.TestThread:37] - 线程[0.4265823186451243]结束==== 2016-01-12 17:33:07,553 [taskExecutor-4] INFO [com.gxx.record.thread.TestThread:37] - 线程[0.1992069353563678]结束==== 2016-01-12 17:33:07,554 [taskExecutor-3] INFO [com.gxx.record.thread.TestThread:37] - 线程[0.5413294134596947]结束====
无需等待线程执行完,立刻返回:执行线程OK~