1,可以使用 Executors 工具类调用newFixedThreadPool,newSingleThreadExecutor,newCachedThreadPool,newScheduledThreadPool 去创建
Executors 工厂创建线程池
newCachedThreadPool:
创建一个可缓存线程池
优点:很灵活,弹性的线程池线程管理,用多少线程给多大的线程池,不用后及时回收,用则新建
缺点:一旦线程无限增长,会导致内存溢出。
newFixedThreadPool :
优点:创建一个固定大小线程池,超出的线程会在队列中等待。
缺点:不支持自定义拒绝策略,大小固定,难以扩展
newScheduledThreadPool :
优点:创建一个固定大小线程池,可以定时或周期性的执行任务。
缺点:任务是单线程方式执行,一旦一个任务失败其他任务也受影响
newSingleThreadExecutor :
优点:创建一个单线程的线程池,保证线程的顺序执行
缺点:不适合并发。。不懂为什么这种操作要用线程池。。为什么不直接用队列
统一缺点:不支持自定义拒绝策略。
TaskThread taskThread = new TaskThread();
ExecutorService threadPool = Executors.newFixedThreadPool(5);
threadPool.execute(() -> {
try {
taskThread.run();
} catch (Exception e) {
e.printStackTrace();
} finally {
threadPool.shutdown();
}
});
threadPool.shutdown();
2,可以通过 new ThreadPoolExecutor 的方式创建,而且这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。
通过ThreadPoolExecutor创建线程池
优点:可以自定义,Executors的底层就是ThreadPoolExecutor,只不过加了很多限制
缺点:没发现缺点,因为上述线程池的底层就是通过它来创建的
TaskThread taskThread = new TaskThread();
ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
1, 1, 10, TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(1),
new ThreadPoolExecutor.DiscardOldestPolicy());
threadPool.execute(() -> {
try {
taskThread.run();// 执行方法
} catch (Exception e) {
e.printStackTrace();
} finally {
threadPool.shutdown();// 关闭线程池
}
});