Java⾃定义参数创建线程池
本⽂主要介绍了Java⾃定义参数创建线程池的⽰例,其中也使⽤了java的并发⼯具类CountDownLatch和CyclicBarrier(顺便练习⼀下他们的⽤法),记录第⼀次发博客
使⽤线程池的好处
降低资源消耗。通过重复利⽤已创建的线程降低线程创建和销毁造成的消耗。
提⾼响应速度。当任务到达时,任务可以不需要的等到线程创建就能⽴即执⾏。
提⾼线程的可管理性。线程是稀缺资源,如果⽆限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使⽤线程池可以进⾏统⼀的分配,调优和监控。
通过Executors⼯具类创建的线程池的弊端
FixedThreadPool和SingleThreadExecutor使⽤⽆界队列LinkedBlockingQueue(队列的容量为 Intger.MAX_VALUE)作为线程池的⼯作队列,可能堆积⼤量的请求,从⽽导致 OOM。
java线程池创建的四种ScheduledThreadPoolExecutor使⽤⽆界队列DelayQueue(队列的容量为 Intger.MAX_VALUE)作为线程池的⼯作队列,可能堆积⼤量的请求,从⽽导致 OOM。
CachedThreadPool允许创建的线程数量为 Integer.MAX_VALUE ,可能会创建⼤量线程,从⽽导致 OOM。
⾃定义参数创建线程池⽰例
package thread;
import urrent.*;
public class ThreadPoolDemo {
//线程池的核⼼线程数量
private static final int CORE_POOL_SIZE = 5;
//线程池的最⼤线程数
private static final int MAX_POOL_SIZE = 10;
//阻塞队列的容量
private static final int QUEUE_CAPACITY = 100;
//当线程数⼤于核⼼线程数时,多余的空闲线程存活的最长时间
private static final Long KEEP_ALIVE_TIME = 1L;
public static int threadNum = 5;
public static void main(String[] args) throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(threadNum);
CyclicBarrier cyclicBarrier = new CyclicBarrier(threadNum);
//使⽤阿⾥巴巴推荐的创建线程池的⽅式
//通过ThreadPoolExecutor构造函数⾃定义参数创建
ThreadPoolExecutor executor = new ThreadPoolExecutor(
CORE_POOL_SIZE,
MAX_POOL_SIZE,
KEEP_ALIVE_TIME,
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(QUEUE_CAPACITY),
//线程池达到饱和之后的拒绝策略,
// 调⽤执⾏⾃⼰的线程运⾏任务,也就是直接在调⽤execute⽅法的线程中运⾏被拒绝的任务
new ThreadPoolExecutor.CallerRunsPolicy());
for (int i = 0; i < threadNum; i++) {
//简洁的Lambda表达式
try {
//当前线程阻塞,直到所有线程都准备就绪
cyclicBarrier.await();
System.out.println( "当前线程: "+ Thread.currentThread().getName() + " 开始⼯作啦");
//模拟业务代码
Thread.sleep(1000);
System.out.println( "当前线程: "+ Thread.currentThread().getName() + " 结束⼯作啦");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
});
}
//主线程等待⼯作线程全部结束
countDownLatch.await();
//关闭线程池
executor.shutdown();
System.out.println("全部线程⼯作完成");    }
}