基本概念
线程池顾名思义线程的池子。
工作者线程和任务队列2个概念组成。
工作者线程主要线程就是一个循环,循环从对列中接受任务执行,任务队列则是保存待执行的任务。
线程池其优点是可以重用线程,避免创建大量的线程,也避免了创建线程的开销。
线程池的基本属性
java中线程池的实现类是ThreadPoolExecutor.
线程池的大小和以下四个参数相关。
1.corePoolSize:核心线程数。
2.maximumPoolSize:最大线程个数。
3.keepAliveTime和unit:空闲线程存活时间。
逻辑是这样的:创建一个线程池后,里面没有一个线程,当新任务到来时,如果当前线程个数小于corePoolSize,无论是否有空闲线程,都创建线程,直到=corePoolSize,而大于corePoolSize后就会进入队列里面排队,如果队列满了,那么就会创建新的线程直到数量达到maximumPoolSize。而keepAliveTime则是当当前线程数目大于corePoolSize时,空闲线程时间达到了这个值,那么这个线程就会被终结掉。
任务拒绝策略:就是上述中maximumPoolSize的任务队列都满了。新任务来了,如何处理?
默认会抛出异常,类型是RejectedExecutionException。
ThreadPoolExecutor.AbortPolicy:这就是默认的方式,抛出异常
ThreadPoolExecutor.DiscardPolicy:静默处理,忽略新任务,不抛异常,也不执行
ThreadPoolExecutor.DiscardOldestPolicy:将等待时间最长的任务扔掉,然后自己排队
ThreadPoolExecutor.CallerRunsPolicy:在任务提交者线程中执行任务,而不是交给线程池中的线程执行
预配置好线程池。
工厂类Executor提供了一些预制好的线程池
public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue
等还有些。这里只是说出几个,看看其实现就知道他的意思了,
package threadPool;import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; public class Test { public static void main(String[] args) { ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 10, 200, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(5)); for (int i = 0; i < 15; i++) { MyTask myTask = new MyTask(i); executor.execute(myTask); System.out.println("线程池中线程数目:" + executor.getPoolSize() + ",队列中等待执行的任务数目:" + executor.getQueue().size() + ",已执行玩别的任务数目:" + executor.getCompletedTaskCount()); } executor.shutdown(); } } class MyTask implements Runnable { private int taskNum; public MyTask(int num) { this.taskNum = num; } @Override public void run() { System.out.println("正在执行task " + taskNum); try { Thread.currentThread().sleep(4000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("task " + taskNum + "执行完毕"); } }
结果如下:
正在执行task 0
线程池中线程数目:1,队列中等待执行的任务数目:0,已执行玩别的任务数目:0
线程池中线程数目:2,队列中等待执行的任务数目:0,已执行玩别的任务数目:0
正在执行task 1
线程池中线程数目:3,队列中等待执行的任务数目:0,已执行玩别的任务数目:0
正在执行task 2
线程池中线程数目:4,队列中等待执行的任务数目:0,已执行玩别的任务数目:0
正在执行task 3
线程池中线程数目:5,队列中等待执行的任务数目:0,已执行玩别的任务数目:0
正在执行task 4
线程池中线程数目:5,队列中等待执行的任务数目:1,已执行玩别的任务数目:0
线程池中线程数目:5,队列中等待执行的任务数目:2,已执行玩别的任务数目:0
线程池中线程数目:5,队列中等待执行的任务数目:3,已执行玩别的任务数目:0
线程池中线程数目:5,队列中等待执行的任务数目:4,已执行玩别的任务数目:0
线程池中线程数目:5,队列中等待执行的任务数目:5,已执行玩别的任务数目:0
线程池中线程数目:6,队列中等待执行的任务数目:5,已执行玩别的任务数目:0
正在执行task 10
线程池中线程数目:7,队列中等待执行的任务数目:5,已执行玩别的任务数目:0
线程池中线程数目:8,队列中等待执行的任务数目:5,已执行玩别的任务数目:0
正在执行task 12
线程池中线程数目:9,队列中等待执行的任务数目:5,已执行玩别的任务数目:0
正在执行task 13
正在执行task 11
线程池中线程数目:10,队列中等待执行的任务数目:5,已执行玩别的任务数目:0
正在执行task 14
task 0执行完毕
正在执行task 5
task 4执行完毕
task 3执行完毕
正在执行task 7
task 2执行完毕
task 1执行完毕
正在执行task 8
正在执行task 6
task 13执行完毕
task 14执行完毕
task 12执行完毕
task 11执行完毕
task 10执行完毕
正在执行task 9
task 5执行完毕
task 7执行完毕
task 8执行完毕
task 6执行完毕
task 9执行完毕
网上直接找了个例子跑了一下,只要理解了上面的原理,这些就很好理解了。