ArrayBlockingQueue、LinkedBlockingQueue、SynchronousQueue:这三个队列各有特色
SynchronousQueue:队列不存任务,需要不停的创建线程包括非核心线程来处理
LinkedBlockingQueue:只有核心线程来处理,队列可以无限延长
ArrayBlockingQueue:先用核心线程来处理任务,核心线程都在工作时加入队列,队列满时建非核心线程处理,非核心线程达到最大数量时,抛出异常
关于ThreadPoolExecutor关键代码execute方法解析:
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
/*
* Proceed in 3 steps:
*
* 1. If fewer than corePoolSize threads are running, try to
* start a new thread with the given command as its first
* task. The call to addWorker atomically checks runState and
* workerCount, and so prevents false alarms that would add
* threads when it shouldn't, by returning false.
*
* 2. If a task can be successfully queued, then we still need
* to double-check whether we should have added a thread
* (because existing ones died since last checking) or that
* the pool shut down since entry into this method. So we
* recheck state and if necessary roll back the enqueuing if
* stopped, or start a new thread if there are none.
*
* 3. If we cannot queue task, then we try to add a new
* thread. If it fails, we know we are shut down or saturated
* and so reject the task.
*/
int c = ctl.get();
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
return;
c = ctl.get();
}
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
if (! isRunning(recheck) && remove(command))
reject(command);
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
else if (!addWorker(command, false))
reject(command);
}
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<10;i++){
MyTask myTask = new MyTask(i);
executor.execute(myTask);
System.out.println("线程中线程数目:"+executor.getPoolSize()+",队列中等待执行的任务数目:"+
executor.getQueue().size()+",已执行完别的任务数目:"+executor.getCompletedTaskCount());
}
}
}
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+"执行完毕");
}
}
合理选择线程池的大小:
CPU密集:Ncpu+1
IO密集:2*Ncpu