阿里要求在创建线程池时 不能使用 Excutors,而要使用ThreadPoolExecutor,具体描述如下:
故研究了一下ThreadPoolExecutor,得出的一点小结论记录如下:
ThreadPoolExecutor的构造方法:
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {}
当提交的线程小于corePoolSize时,创建新线程来启动
如果提交线程数大于corePoolSize时,将线程加入workQueue中,如果workQueue满了,则继续创建新线程直到线程数等于maximumPoolSize,此时再提交新的线程,则抛出java.util.concurrent.RejectedExecutionException异常
例
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(corePoolSize,
maximumPoolSize, 0L, TimeUnit.SECONDS, new MyBlockingQueue(queueSize));
上述代码中maximumPoolSize>=corePoolSize,否则会抛出java.lang.IllegalArgumentException异常
- 若提交n个线程(0<=n<=corePoolSize),则线程池创建n个线程并执行
- 若提交n(corePoolSize < n<=corePoolSize+queueSize),则前corePoolSize个提交的线程直接被创建运行,( n-corePoolSize )个线程加入workQueue中等待执行
- 若提交n(corePoolSize+queueSize < n<=maximumPoolSize+queueSize , corePoolSize < maximumPoolSize)则前corePoolSize个提交的线程直接被创建运行,( n-corePoolSize
)个线程加入workQueue中等待执行,(n-corePoolSize-queueSize)再创建新的线程来执行
测试代码
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* @author ElinZhou
* @version $Id: ThreadPoolTest.java , v 0.1 2017/1/10 10:33 ElinZhou Exp $
*/
public class ThreadPoolTest {
public static void main(String... args) throws Exception {
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5, 6, 0L,
TimeUnit.SECONDS, new MyBlockingQueue(1));
int nThread = 8;
for (int i = 0; i < nThread; i++) {
System.out.println("create thread " + i);
Thread thread = new Thread(new MyRunnable(i));
threadPoolExecutor.submit(thread);
}
// TimeUnit.SECONDS.sleep(5);
}
}
class MyBlockingQueue extends LinkedBlockingQueue<Runnable> {
public MyBlockingQueue() {
super();
}
public MyBlockingQueue(int nThread) {
super(nThread);
}
@Override
public boolean offer(Runnable runnable) {
System.out.println("invoke offer method:" + runnable);
return super.offer(runnable);
}
}
class MyRunnable implements Runnable {
private int id;
public MyRunnable(int id) {
this.id = id;
}
@Override
public void run() {
System.out.println(id + " start at:" + System.currentTimeMillis());
try {
Thread.sleep(500);
} catch (InterruptedException e) {
System.out.println(id + " interrupted at:" + System.currentTimeMillis());
}
System.out.println("------" + id + " end at:" + System.currentTimeMillis());
}
@Override
public String toString() {
return "MyRunnable-" + id;
}
}