Java中常见的并发工具类

1. CountDownLatch

CountDownLatch允许一个或多个线程等待其他线程完成操作。简单理解便是阻塞当前线程后不断去监听其他线程的状态,等到其他线程都完成操作后,当前线程才会继续执行,但该类监听粒度又比较细。

public class CountDownLatchTest {
    public static void main(String[] args) throws InterruptedException {
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("1");
                downLatch.countDown();
                System.out.println("2");
                downLatch.countDown();
            }
        }).start();
        downLatch.await();
        System.out.println("3");
    }
    private static CountDownLatch downLatch = new CountDownLatch(2);
}

运行结果

构造函数的参数代表监听点的个数,每调用一次countDown,参数值便会-1,直到参数值变成零(可以理解为是一个计数器)。downLatch.await()阻塞该线程直到计数器变成0。这里有个有趣的点,比如监听的点有2个,但构造函数传入的参数>2,此时线程则会一直出于阻塞状态,但我们又不能让线程一直处于阻塞状态,可以使用带时间戳的await方法,await(long time, TineUnit unit),超时便不会阻塞线程。

2. 同步屏障CyclicBarrier

同步屏障CyclicBarrier跟CountDownLatch很类似,但相比CountDownLatch会更加有趣些,可以看成是CountDownLatch的改良版。CyclicBarrier通过设置一个屏幕,让线程到达时被阻塞,直到最后一个线程到达屏障时,屏障才打开,所有被拦截的线程才会继续执行。

public class CyclicBarrierTest {
    public static void main(String[] args) throws Exception{
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("1");
                try {
                    barrier.await();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                System.out.println("2");
            }
        }).start();
        System.out.println("3");
        barrier.await();
        System.out.println("4");
    }
    private static CyclicBarrier barrier = new CyclicBarrier(2);
}

运行结果

CyclicBarrier监听的是线程而不再是某一个点,相比CountDownLatch,可以使用reset()重置,因此计算错误,也可以重试。getNumberWaiting()获取阻塞的线程数;isBroken()获取阻塞的线程是否被中断。

3. 控制并发线程数的Semaphore

Semaphore可以用作流量控制,特别是公共资源有点的场景下,控制指定的线程数能获取到资源,比如:数据库连接池,也可以实现限流等。主要有以下方法。

请求资源:acquire() / tryAcquire()
释放资源:release()

还有一些其他的方法,返回可以的许可数、获取等待的线程数、是否有线程正在等待获取许可数等等,有需要可以直接查看API文档。

你可能感兴趣的:(Java基础)