线程池为线程生命周期开销问题和资源不足问题提供了解决方案。通过对多个任务重用线程,线程创建的开销被分摊到了多个任务上。其好处是,因为在请求到达时线程已经存在,所以无意中也消除了线程创建所带来的延迟。这样,就可以立即为请求服务,使应用程序响应更快。而且,通过适当地调整线程池中的线程数目,也就是当请求的数目超过某个阈值时,就强制其它任何新到的请求一直等待,直到获得一个线程来处理为止,从而可以防止资源不足。
使用spring管理线程池的使用
1、创建线程池的配置信息threads.properties
####业务线程池配置####
#是否启用自定义线程池。true时启动,以下参数生效
handler.threads.custom=false
#核心线程数
handler.threads.corePoolSize=20
#最大线程数
handler.threads.maximumPoolSize=1000
#空闲线程存活时间,单位秒
handler.threads.keepAliveTime=100
#工作队列大小,为0是无限大
handler.threads.workQueue=0
2、创建 线程池 配置,ThreadsPoolConfig.java
package com.hk.core.concurrent;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
* 线程池 配置
*/
@Component
public class ThreadsPoolConfig {
/**
* 是否开启自定义线程池
*/
@Value("${handler.threads.custom}")
private boolean custom;
/**
* 核心线程数
*/
@Value("${handler.threads.corePoolSize}")
private int corePoolSize;
/**
* 线程池最大线程数
*/
@Value("${handler.threads.maximumPoolSize}")
private int maximumPoolSize;
/**
* 空闲线程存活时间(对核心线程无效)
*/
@Value("${handler.threads.keepAliveTime}")
private long keepAliveTime;
/**
* 任务队列大小,0时为无界队列
*/
@Value("${handler.threads.workQueue}")
private int workQueue;
public boolean isCustom() {
return custom;
}
public void setCustom(boolean custom) {
this.custom = custom;
}
public int getCorePoolSize() {
return corePoolSize;
}
public void setCorePoolSize(int corePoolSize) {
this.corePoolSize = corePoolSize;
}
public int getMaximumPoolSize() {
return maximumPoolSize;
}
public void setMaximumPoolSize(int maximumPoolSize) {
this.maximumPoolSize = maximumPoolSize;
}
public long getKeepAliveTime() {
return keepAliveTime;
}
public void setKeepAliveTime(long keepAliveTime) {
this.keepAliveTime = keepAliveTime;
}
public int getWorkQueue() {
return workQueue;
}
public void setWorkQueue(int workQueue) {
this.workQueue = workQueue;
}
}
3、创建 线程池 处理器管理线程 HandlerThreadsPool.java
package com.hk.core.concurrent;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import javax.annotation.PreDestroy;
/**
* 线程管理器
*/
public class HandlerThreadsPool {
public ExecutorService executorService;
public HandlerThreadsPool() {
// TODO Auto-generated constructor stub
this.executorService=Executors.newCachedThreadPool();
}
public HandlerThreadsPool(ThreadsPoolConfig config) {
// TODO Auto-generated constructor stub
if(config.isCustom()){
BlockingQueue<Runnable> queue=null;
if(config.getWorkQueue()>0){
queue=new LinkedBlockingQueue<Runnable>(config.getWorkQueue()); // 一般使用 LinkedBlockingQueue 队列
}else{
queue=new LinkedBlockingQueue<Runnable>();
} // 配置线程池信息
this.executorService=new ThreadPoolExecutor(
config.getCorePoolSize(),
config.getMaximumPoolSize(),
config.getKeepAliveTime(),
TimeUnit.SECONDS,
queue,
new ThreadPoolExecutor.AbortPolicy()//拒绝策略,任务队列满后,新的任务将被丢弃,并抛出异常
);
}else{
this.executorService=Executors.newCachedThreadPool();
}
} /* * 创建线程,对线程处理事件 */
public void execute(Runnable runnable){
executorService.execute(runnable);
}
/* * 对象销毁时,销毁线程 */
@PreDestroy
public void stop() {
executorService.shutdown();
}
}
4、使用线程池
package com.hk.core.concurrent;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class MsgHandler implements Runnable{
@Autowired
private ThreadsPoolConfig config; // 注入 配置
@Override
public void run() {
// do 这里 写 处理的逻辑
System.out.println("创建线程 处理事务....");
}
@PostConstruct
public void loadThreadsPool(){
// 初始化 线程池
HandlerThreadsPool handlerThreadsPool=new HandlerThreadsPool(config);
//调用线程池,创建线程 。处理事件
handlerThreadsPool.execute(new MsgHandler());
}
}
关系中断线程的使用(简略)
//线程,可用于固定线程池大小,重复动作使用某个线程强制停止
new Thread(() -> {
},"线程名称").start();
//方法
private static boolean threadIsRunning() {
boolean flag = false;
//getAllStackTraces()方法的作用是返回所有活动线程的堆栈跟踪的一个映射。映射键是线程,而每个映 射值都是一个 StackTraceElement 数组,该数组表示相应Thread的堆栈转 储。返回的堆栈跟踪的格式都是针对getStackTrace方法指定的。在调用该 方法的同时,线程可能也在执行。每个线程的堆栈跟踪仅代表一个快照, 并且每个堆栈跟踪都可以在不同时间获得。如果虚拟机没有线程的堆栈跟 踪信息,则映射值中将返回一个零长度数组。
for (Thread t : Thread.getAllStackTraces().keySet()) {
if ("线程名称".equals(t.getName())) {
LOG.info("正在发送上一线程中断指令...");
//interrupt()方法的作用是中断对应的线程
t.interrupt();
LOG.info("已发送中断指令");
flag = true;
}
}
return flag;
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。