JUC练习10——线程池
一,概念
池化技术:线程的运行是占用系统资源的,每个线程的诞生都需要有(创建——初始化——使用——销毁)等步骤,为了避免多次重复的创建和销毁线程利用率,提出了池化技术,先创建好进程放到进程池中,如果要使用进程了就从池里面拿来用,用完之后就还回去。这就是池化技术
传统:创建线程——》使用线程——》销毁进程
池化技术:取出线程)——》使用线程——》归还线程
池化技术优点:降低资源消耗,提高系统的速度,方便对进程的管理
二,线程池
1,三大方法
/**
* newSingleThreadExecutor 线程池中就一个线程
* newFixedThreadPool 通过参数自行定义线程池的大小
* newCachedThreadPool 根据实际情况自动伸缩线程池的大小
*/
public static void test6()
{
ExecutorService threadPoll1 = Executors.newSingleThreadExecutor();
ExecutorService threadPoll2 = Executors.newFixedThreadPool(3);
ExecutorService threadPoll3 = Executors.newCachedThreadPool();
// for (int i=0;i<10;i++)
// {
// threadPoll1.execute(()->
// {
// System.out.println(Thread.currentThread().getName()+"——》OK");
// });
// }
// threadPoll1.shutdown();
// for (int i=0;i<10;i++)
// {
// threadPoll2.execute(()->
// {
// System.out.println(Thread.currentThread().getName()+"——》OK");
// });
// }
// threadPoll2.shutdown();
for (int i=0;i<10;i++)
{
threadPoll3.execute(()->
{
System.out.println(Thread.currentThread().getName()+"——》OK");
});
}
threadPoll3.shutdown();
}
源码分析:
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,//21亿
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
这三个方法的本质都是ThreadPoolExecutor
public ThreadPoolExecutor(int corePoolSize,//核心线程数
int maximumPoolSize,//最大线程数
long keepAliveTime,//连接保存的时间
TimeUnit unit,//时间单位
BlockingQueue<Runnable> workQueue,//阻塞队列
ThreadFactory threadFactory,//线程工厂
RejectedExecutionHandler handler) {//拒绝策略
if (corePoolSize < 0 ||
maximumPoolSize <= 0 ||
maximumPoolSize < corePoolSize ||
keepAliveTime < 0)
throw new IllegalArgumentException();
if (workQueue == null || threadFactory == null || handler == null)
throw new NullPointerException();
this.acc = (System.getSecurityManager() == null)
? null
: AccessController.getContext();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
结论:

2,7大参数,使用原始方法进行线程池的创建
int corePoolSize,//核心线程数
int maximumPoolSize,//最大线程数
long keepAliveTime,//连接保存的时间
TimeUnit unit,//时间单位
BlockingQueue<Runnable> workQueue,//阻塞队列
ThreadFactory threadFactory,//线程工厂
RejectedExecutionHandler handler) {//拒绝策略
public static void main(String[] args) {
test7();
}
/**
* 使用默认的线程池方式进行创建,根据需求去定制
* 如下配置:核心线程为2,最大线程为5,超时时间为3秒,处理不了的请求放入的队列长度为5,使用的拒绝策略为抛异常
* 正常情况下是核心的2个线程加上队列来处理请求,如果请求数>核心线程数据+队列长度,会申请新的线程加入处理(当前线程数<最大线程数)
*/
public static void test7()
{
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2,
5,
3,
TimeUnit.SECONDS,
new LinkedBlockingDeque<>(5),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy());
//i<7 i<8 i<5 进行测试
for (int i=0;i<7;i++)
{
threadPoolExecutor.execute(()->
{
System.out.println(Thread.currentThread().getName()+"——》OK");
});
}
threadPoolExecutor.shutdown();
}
3,最大线程数该如何定义
//1,cpu密集型 获取cpu的核数作为线程的最大数 Runtime.getRuntime().availableProcessors()
//2,IO密集型 判断你的程序中十分耗IO的线程有几个,最大线程数大于它即可
浙公网安备 33010602011771号