并发学习
# ThreadPoolExecutor
# 构造参数
拒绝策略 | |
---|---|
corePoolSize | 核心线程数 |
maximumPoolSize | 最大线程数 |
TimeUnit | 线程活跃时间 |
BlockingQueue | 活跃时间单位 |
workQueue | 工作队列 |
ThreadFactory | 线程工程 |
RejectedExecutionHandler | 拒绝策略 |
线程池可执行线程数: 最大线程数 + 等待队列线程数
超出等待队列的线程将进入拒绝策略
等待队列BlockingQueue
LinkedBlockingQueue 基于链表实现
使用同一个putLock
和takeLock
分别控制读写,并发能力强
public LinkedBlockingQueue(int capacity) {
if (capacity <= 0) throw new IllegalArgumentException();
this.capacity = capacity;
last = head = new Node<E>(null);
}
ArrayBlockingQueue 基于数组实现
使用同一个lock
控制读写,无法真正实现读写并行
public ArrayBlockingQueue(int capacity, boolean fair) {
if (capacity <= 0)
throw new IllegalArgumentException();
this.items = new Object[capacity];
lock = new ReentrantLock(fair);
notEmpty = lock.newCondition();
notFull = lock.newCondition();
}
# 拒绝策略
拒绝策略 | |
---|---|
new ThreadPoolExecutor.AbortPolicy() | 超出抛异常 |
new ThreadPoolExecutor.CallerRunsPolicy() | 由调用方线程执行 |
new ThreadPoolExecutor.DiscardOldestPolicy() | 丢弃老的任务 |
new ThreadPoolExecutor.DiscardPolicy() | 丢弃任务 |
# CyclicBarrier
可循环利用的屏障,用于所有线程都等待完成后才会继续下一步行动的场景。
使用
CyclicBarrier
的构造函数如下
public CyclicBarrier(int parties);
public CyclicBarrier(int parties, Runnable barrierAction);
参数代表的意思如下
- parties 参与线程个数
- barrierAction 需要执行的线程
重要方法
public int await() throws InterruptedException, BrokenBarrierException
public int await(long timeout, TimeUnit unit) throws InterruptedException, BrokenBarrierException, TimeoutException
await()
表示当前线程已经到了栅栏处等待
await(long timeout, TimeUnit unit)
在等待的时候设置了超时时间,如果超时的话,会抛出java.util.concurrent.TimeoutException
# 示例
3人闯关,但是必须等待每个人都结束后才能开始下一关
private static final int THREADS = 3;
private static final int TIME_OUT = 3;
public static void main(String[] args) {
CyclicBarrier barrier = new CyclicBarrier(THREADS,()->{
System.out.println("go go go ... ");
});
for (int i = 0; i < THREADS; i++) {
ThreadUtil.execute(()->{
try {
run(barrier);
System.out.println("通关啦111");
} catch (Exception e) {;
throw new RuntimeException(e);
}
});
System.out.println("通关啦222");
}
System.out.println("通关啦");
}
private static void run(CyclicBarrier barrier) throws Exception {
String name = Thread.currentThread().getName();
System.out.println(name+":进入游戏,开始第一关");
barrier.await(TIME_OUT, TimeUnit.SECONDS);
System.out.println(name+":来到了第二关");
barrier.await(TIME_OUT, TimeUnit.SECONDS);
System.out.println(name+":来到了进入了第三关");
barrier.await(TIME_OUT, TimeUnit.SECONDS);
System.out.println(name+":开始结算");
}
上次更新: 2024/11/05, 08:29:31