线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。线程池线程都是后台线程。每个线程都使用默认的堆栈大小,以默认的优先级运行,并处于多线程单元中。如果某个线程在托管代码中空闲(如正在等待某个事件),则线程池将插入另一个辅助线程来使所有处理器保持繁忙。如果所有线程池线程都始终保持繁忙,但队列中包含挂起的工作,则线程池将在一段时间后创建另一个辅助线程但线程的数目永远不会超过最大值。超过最大值的线程可以排队,但他们要等到其他线程完成后才启动。
创建线程池
//创建可伸缩的线程池 来的多开的多
ExecutorService exchanger = Executors.newCachedThreadPool();
//创建固定的线程池 最大5个
ExecutorService executorService = Executors.newFixedThreadPool(5);
//开放单一的线程
ExecutorService executorService1 = Executors.newSingleThreadExecutor();
这三个线程池的底层都是手动实现的线程池
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
我们也来手动创建
需要手动创建的构造函数有七大参数
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
源码解释:
corePoolSize - 线程池中保留的线程数,即使它们处于空闲状态,除非设置了 allowCoreThreadTimeOut maximumPoolSize - 池中允许的最大线程数
keepAliveTime - 当线程数大于核心时,这是多余的空闲线程在终止前等待新任务的最长时间。 unit – keepAliveTime 参数的时间单位
workQueue – 用于在执行任务之前保存任务的队列。此队列将仅保存由 execute 方法提交的 Runnable 任务。
第一个参数是核心线程大小,意思就是处于工作状态的就是这两个
第二个是核心线程同时工作的最大线程数量。
第三个是超时等待,设置1小时 当核心以外的线程1小时没有任务就会被释放。
第四个是单位。
第五个参数是阻塞队列,就相当于候客区,当候客区满了就会接着开启线程知道最大。
第六个就是传入默认的线程工厂。
第七个是拒绝策略。
核心数加阻塞队列中的线程数满了就会开启一个最大线程
比如核心数3 阻塞队列空间3当开启7个线程时核心数变为4 最大为核心线程同时工作的最大线程数量。
所以能够运行的最大线程数时核心加阻塞队列。
超出最大值就会被拒绝策略接收
四种拒绝策略。
System.out.println(Runtime.getRuntime().availableProcessors());
获取cpu的核数。