示例一(使用Executors工具类代为创建):
对应的API:
Executors.newCachedThreadPool():无限线程池。
Executors.newFixedThreadPool(nThreads):创建固定大小的线程池。
Executors.newSingleThreadExecutor():创建单个线程的线程池。
代码如下:
public class TestThreadPool {
public static void main(String[] args) {
ExecutorService threadPool =Executors.newFixedThreadPool(20);
threadPool.execute(new Runnable() {
@Override
public void run() {
System.out.println("aaa");
}
});
}
}
这是最简单的一种方法,但是这有很多不可控性,在阿里编程规约里是禁止这样来写的。因为这样的写法会让我们对他的内部参数缺乏管理。上面的例子中所创建的队列是LinkedBlockingQueue,并且是按最大值构建的。
public LinkedBlockingQueue() {
this(Integer.MAX_VALUE);
}
示例二(自定义构造参数-推荐):
能够对线程池更精细的控制
对应的API:
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue, RejectedExecutionHandler handler)
这几个参数的作用是:
corePoolSize 为线程池的基本大小。
maximumPoolSize 为线程池最大线程大小。
keepAliveTime 和 unit 则是线程空闲后的存活时间。
workQueue 用于存放任务的阻塞队列。
1、SynchronousQueue
2、LinkedBlockingQueue
3、ArrayBlockingQueuehandler 当队列和最大线程池都满了之后的饱和策略。
1、直接丢弃(DiscardPolicy)
2、丢弃队列中最老的任务(DiscardOldestPolicy)。
3、抛异常(AbortPolicy)
4、将任务分给调用线程来执行(CallerRunsPolicy)。
代码如下:
public class TestThreadPool {
public static void main(String[] args) {
int coreSize=10;
int maxSize=20;
int time=10;
BlockingQueue blockingQueue=new LinkedBlockingDeque(20);
DefaultThreadFactory defaultThreadFactory =new DefaultThreadFactory("factory-name");
ThreadPoolExecutor threadPool=new ThreadPoolExecutor(coreSize,maxSize,time,TimeUnit.SECONDS,
blockingQueue,defaultThreadFactory,new
ThreadPoolExecutor.AbortPolicy());
threadPool.execute(new Runnable() {
@Override
public void run() {
System.out.println("aaa");
}
});
}
}
线程池的任务执行流程如下:
当线程池小于corePoolSize时,新提交任务将创建一个新线程执行任务,即使此时线程池中存在空闲线程。
当线程池达到corePoolSize时,新提交任务将被放入workQueue中,等待线程池中任务调度执行
当workQueue已满,且maximumPoolSize>corePoolSize时,新提交任务会创建新线程执行任务
当提交任务数超过maximumPoolSize时,新提交任务由RejectedExecutionHandler处理
当线程池中超过corePoolSize线程,空闲时间达到keepAliveTime时,关闭空闲线程
当设置allowCoreThreadTimeOut(true)时,线程池中corePoolSize线程空闲时间达到keepAliveTime也将关闭
如果想了解源码,请参考https://www.jianshu.com/p/d2729853c4da