用户工具

站点工具


分享:技术:池:线程池

这是本文档旧的修订版!


线程池

线程池的原理及实现

线程池的好处

由于创建和关闭线程比较耗资源耗时,所以使用线程池,在应用启动时候,就创建多个线程,减少用户请求时创建和关闭线程的时间;而且使用完毕,线程不关闭,可以重复使用,提高并发性能

spring实现线程池

application-pool.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>

ThreadController.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~";
	}
}

TestThread.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 + "]结束====");
	}
 
}

请求地址

并发日志

并发日志.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]结束====

前端输出

无序等待线程执行完,立马返回:执行线程OK~

分享/技术/池/线程池.1452591335.txt.gz · 最后更改: 2016/01/12 17:35 由 gxx