这里会显示出您选择的修订版和当前版本之间的差别。
后一修订版 | 前一修订版 | ||
分享:技术:池:线程池 [2015/12/21 11:56] gxx 创建 |
分享:技术:池:线程池 [2016/01/12 17:36] (当前版本) gxx [前端输出] |
||
---|---|---|---|
行 1: | 行 1: | ||
====== 线程池 ====== | ====== 线程池 ====== | ||
+ | ===== 线程池的原理及实现 ===== | ||
+ | http://blog.csdn.net/hsuxu/article/details/8985931 | ||
+ | ===== 线程池的好处 ===== | ||
+ | 由于创建和关闭线程比较耗资源耗时,所以使用线程池,在应用启动时候,就创建多个线程,减少用户请求时创建和关闭线程的时间;而且使用完毕,线程不关闭,可以重复使用,提高并发性能 | ||
+ | ===== spring实现线程池 ===== | ||
+ | ==== application-pool.xml ==== | ||
+ | <file xml application-pool.xml> | ||
+ | <?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> | ||
+ | </file> | ||
+ | ==== ThreadController.java ==== | ||
+ | <file java ThreadController.java> | ||
+ | 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~"; | ||
+ | } | ||
+ | } | ||
+ | </file> | ||
+ | ==== TestThread.java ==== | ||
+ | <file java TestThread.java> | ||
+ | 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 + "]结束===="); | ||
+ | } | ||
+ | |||
+ | } | ||
+ | </file> | ||
+ | ===== 请求地址 ===== | ||
+ | [Protocol]://[IP]:[Port]/record/thread/execute.htm | ||
+ | ===== 并发日志 ===== | ||
+ | <file txt 并发日志.txt> | ||
+ | 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]结束==== | ||
+ | </file> | ||
+ | ===== 前端输出 ===== | ||
+ | 无需等待线程执行完,立刻返回:执行线程OK~ |