常用的并发工具类

36 阅读1分钟

同步屏障CyclicBarrier

/ˈsaɪklɪk ˈbæriə(r)/
CyclicBarrier的字面意思是可循环(Cyclic)使用的屏障(Barrier)。让一组线程到达一个屏障(也叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会打开。 线程调用await()方法会被阻塞,直到所有线程到达屏障时,屏障才会打开

其他API:
cyclicBarrier.getNumberWaiting()获取阻塞线程数
cyclicBarrier.isBroken()了解阻塞线程是否被中断

例子:集齐7龙珠就可以召唤神龙。未集齐则阻塞main线程

CyclicBarrier cyclicBarrier = new CyclicBarrier(7, ()->{
    System.out.println("7龙珠集齐完毕,召唤神龙");
});

for (int i = 1; i <= 7; i++) {
    new Thread(()->{
        try {
            System.out.println(Thread.currentThread().getName() + "找到一颗龙珠!");
            cyclicBarrier.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (BrokenBarrierException e) {
            e.printStackTrace();
        }
        
    },"t" + i).start();
}

等待多线程完成CountDownLatch

使用join

join()方法,底层调用wait()方法,让当前线程阻塞。当前线程执行完毕后,JVM内部会唤醒该线程,比如调用当前线程的notifyAll()方法

Thread t1 = new Thread(()->{
    try {
        TimeUnit.SECONDS.sleep(3);
        System.out.println("t1执行完毕");
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
});
Thread t2 = new Thread(()->{
    try {
        TimeUnit.SECONDS.sleep(2);
        System.out.println("t2执行完毕");
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
});
t1.start();
t2.start();

t1.join();
t2.join();

System.out.println("main线程执行完毕");

结果:
t2执行完毕
t1执行完毕
main线程执行完毕

使用CountDownLatch

CountDownLatch主要有两个方法,调用await方法的线程会阻塞,调用countDown方法的线程不会阻塞,计算器会减1。当计数器为0时,因为调用await方法被阻塞的线程会被唤醒,继续执行。

CountDownLatch countDownLatch = new CountDownLatch(2);

Thread t1 = new Thread(()->{
    try {
        TimeUnit.SECONDS.sleep(3);
        System.out.println("t1执行完毕");
        countDownLatch.countDown();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
});

Thread t2 = new Thread(()->{
    try {
        TimeUnit.SECONDS.sleep(2);
        System.out.println("t2执行完毕");
        countDownLatch.countDown();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
});
t1.start();
t2.start();

countDownLatch.await();

System.out.println("main线程执行完毕");

控制线程并发数量Semaphore

可用作流量控制