最近在看java的线程池,对于里面的三种缓存队列里面进行对比学习了下,感觉自己测试下来的结果和网上有些知识点不同相同,所以还希望有人能帮我解惑下。
队列 | 简单解释 |
SynchrousQueue | 不会保存提交任务,超出直接corePoolSize个任务,直接创建新的线程来执行任务,直到(corePoolSize+新建线程)> maximumPoolSize。不是核心线程就是新建线程。 |
LinkedBlockingQueue | 基于链表的先进先出,无界队列。超出直接corePoolSize个任务,则加入到该队列中,直到资源耗尽,所以maximumPoolSize不起作用 |
ArrayBlockingQueue | 基于数组的先进先出,创建时必须指定大小,超出直接corePoolSize个任务,则加入到该队列中,只能加该queue设置的大小,其余的任务则创建线程,直到(corePoolSize+新建线程)> maximumPoolSize |
创建一个corePoolSize为2,maximumPoolSize为3的线程池。执行6个任务。根据我的理解,SynchrousQueue是个一个无缓存的队列(理论依据为SynchrousQueue源码可以看到:isEmpty()始终为true;size()始终返回0)
根据参数设置应该只可以执行3个任务:
2个核心线程执行2个任务; |
第3个任务的时候,创建线程来执行任务3; |
当第4个任务来的时候,此时已经超过了maximumPoolSize,所以拒绝任务。(但是网上有些说法是这里是可以在缓存一个任务到队列中,我不太理解这种说法,还希望有人能解答下。) |
创建线程池代码如下:
/**
* SynchronousQueue
*/
private static void syncQueue() {
System.out.println("\n\n =======SynchronousQueue====== \n\n");
Executor executors = new ThreadPoolExecutor(
2, 3, 30, TimeUnit.SECONDS,
new SynchronousQueue(),
new RejectHandler());
execute(executors);
}
执行结果如下:(跟我的预想是一样的)
1 is running...
4 is rejected ^^ //4被拒
2 is running...
3 is running...
5 is rejected ^^ //5被拒
6 is rejected ^^ //6被拒
3 is end !!!
1 is end !!!
2 is end !!!
创建一个corePoolSize为2,maximumPoolSize为3的线程池。其中ArrayBlockingQueue设置缓存2个任务。执行6个任务。ArrayBlockingQueue为有界队列:
任务1和2在核心线程中执行; |
任务3和4进来的时候,是放到ArrayBlockingQueue缓存队列中的,并且只能放2个(ArrayBlockingQueue设置的大小为2); |
任务5和6进来的时候,任务5新建线程来执行任务,已经达到最大线程数3,所以任务6拒绝; |
当有线程执行完的时候,再将任务3和4从队列中取出执行 |
创建线程池代码如下:
/**
* ArrayBlockingQueue
*/
private static void arrayQueue() {
System.out.println("\n\n =======ArrayBlockingQueue====== \n\n");
Executor executors = new ThreadPoolExecutor(
2, 3, 30, TimeUnit.SECONDS,
new ArrayBlockingQueue(2),
new RejectHandler());
execute(executors);
}
执行结果如下
1 is running...
2 is running...
6 is rejected ^^ //6被拒
5 is running... //5新建线程执行
1 is end !!!
2 is end !!!
3 is running... //1和2执行完之后3和4才执行
4 is running...
5 is end !!!
创建一个corePoolSize为2,maximumPoolSize为3的线程池。无界队列。同样执行6个任务
核心线程执行任务1和2,其它的任务3~6放到队列中 |
执行完1和2,将3和4从队列中取出执行 |
执行完3和4,将5和6从队列中取出 |
/**
* LinkedBlockingQueue
*/
private static void linkedQueue() {
System.out.println("\n\n =======LinkedBlockingQueue====== \n\n");
Executor executors = new ThreadPoolExecutor(
2, 3, 30, TimeUnit.SECONDS,
new LinkedBlockingQueue(),
new RejectHandler());
execute(executors);
}
运行结果如下:
1 is running...
2 is running... //中间线程休眠
2 is end !!! //10s之后才运行完
1 is end !!!
3 is running... //任务3和4才执行
4 is running...
4 is end !!!
3 is end !!!
6 is running...
5 is running...
5 is end !!!
6 is end !!!
队列 | 创建线程数 | 正在可以去有执行意愿(放入到缓存队列和执行线程中)的最多任务数 | 可以缓存个数 |
SynchrousQueue | maximumPoolSize | (corePoolSize+创建的线程数) <=maximumPoolSize | 无 |
ArrayBlockingQueue | maximumPoolSize | (corePoolSize+创建的线程数)(相加数要<=maximumPoolSize)+ArrayBlockingQueue设置的缓存数 | ArrayBlockingQueue设置的缓存数 |
LinkedBlockingQueue | corePoolSize | corePoolSize+LinkedBlockingQueue缓存的无界任务 | 无界 |
总的代码如下:
public static void main(String[] args) {
queue();
}
/***
* 执行不同的缓存队列
*/
private static void queue() {
syncQueue();
//arrayQueue();
//linkedQueue();
}
/**
* ArrayBlockingQueue
*/
private static void arrayQueue() {
System.out.println("\n\n =======ArrayBlockingQueue====== \n\n");
Executor executors = new ThreadPoolExecutor(
2, 3, 30, TimeUnit.SECONDS,
new ArrayBlockingQueue(2),
new RejectHandler());
execute(executors);
}
/**
* LinkedBlockingQueue
*/
private static void linkedQueue() {
System.out.println("\n\n =======LinkedBlockingQueue====== \n\n");
Executor executors = new ThreadPoolExecutor(
2, 3, 30, TimeUnit.SECONDS,
new LinkedBlockingQueue(),
new RejectHandler());
execute(executors);
}
/**
* SynchronousQueue
*/
private static void syncQueue() {
System.out.println("\n\n =======SynchronousQueue====== \n\n");
Executor executors = new ThreadPoolExecutor(
2, 3, 30, TimeUnit.SECONDS,
new SynchronousQueue(),
new RejectHandler());
execute(executors);
}
private static void execute(Executor executors) {
executors.execute(new NameRunnable(1));
executors.execute(new NameRunnable(2));
executors.execute(new NameRunnable(3));
executors.execute(new NameRunnable(4));
executors.execute(new NameRunnable(5));
executors.execute(new NameRunnable(6));
}
/***
* 创建一个有名字的runnable对象
*/
private static class NameRunnable implements Runnable {
private int name;
public NameRunnable(int name) {
this.name = name;
}
public int getName() {
return name;
}
@Override
public void run() {
System.out.println(name + " is running... ");
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(name + " is end !!! ");
}
}
/***
* 拒绝的Runnable
*/
private static class RejectHandler implements RejectedExecutionHandler {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
NameRunnable name = (NameRunnable) r;
System.out.print(name.getName() + " is rejected ^^\n");
}
}
}