最近在看java的线程池,对于里面的三种缓存队列里面进行对比学习了下,感觉自己测试下来的结果和网上有些知识点不同相同,所以还希望有人能帮我解惑下。
队列 | 简单解释 |
---|---|
SynchrousQueue | 不会保存提交任务,超出直接corePoolSize个任务,直接创建新的线程来执行任务,直到(corePoolSize+新建线程)> maximumPoolSize。不是核心线程就是新建线程。 |
LinkedBlockingQueue | 基于链表的先进先出,无界队列。超出直接corePoolSize个任务,则加入到该队列中,直到资源耗尽,所以maximumPoolSize不起作用 |
ArrayBlockingQueue | 不会保存提交任务,超出直接corePoolSize个任务,直接创建新的线程来执行任务,直到(corePoolSize+新建线程)> maximumPoolSize。不是核心线程就是新建线程。 |
创建一个corePoolSize为2,maximumPoolSize为3的线程池。执行6个任务。根据我的理解,SynchrousQueue是个一个无缓存的队列(理论依据为SynchrousQueue源码可以看到:isEmpty()始终为true;size()始终返回0)
/**
* SynchronousQueue
*/
private static void syncQueue() {
System.out.println("\n\n =======SynchronousQueue====== \n\n");
Executor executors = new ThreadPoolExecutor(
2, 3, 30, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>(),
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为有界队列:
/**
* ArrayBlockingQueue
*/
private static void arrayQueue() {
System.out.println("\n\n =======ArrayBlockingQueue====== \n\n");
Executor executors = new ThreadPoolExecutor(
2, 3, 30, TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(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个任务
/**
* LinkedBlockingQueue
*/
private static void linkedQueue() {
System.out.println("\n\n =======LinkedBlockingQueue====== \n\n");
Executor executors = new ThreadPoolExecutor(
2, 3, 30, TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(),
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 !!!
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<Runnable>(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<Runnable>(),
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<Runnable>(),
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");
}
}
}