Fork me on GitHub

并发工具类

注意:所有文章除特别说明外,转载请注明出处.

第八章 Java中的并发工具类

[TOC]

CountDownLatch、CyclicBarrier和Semaphore工具类提供一种并发流程控制手段,Exchanger工具类提供了在线程间交换数据的一种手段。

8.1 等待多线程完成的CountDownLatch

CountDownLatch 允许一个或多个线程等待其它线程完成操作。

需求:我们需要解析一个Excel里多个sheet的数据,此时可以考虑使用多线程,每个线程解析一个sheet里的数据,等到所有的sheet都解析完成之后,程序需要提示解析完成。

提示:join用于让当前线程等待join线程执行结束。其实现原理是不停的检查join线程是否存活,如果join线程存活则让当前线程永远等待。

注意:直到join线程中止后,线程的this.notifyAll()方法会被调用,调用notifyAll()方法是在JVM里实现的。

CountDownLatch 的构造函数接收一个int类型的参数作为计数器,如果想等待N个点完成,就传入N。

当调用CountDownLatch的countDown方法时,N就会减1,CountDownLatch的await()方法会阻塞当前线程,直到N变为0。

await() 阻塞当前线程

如果有某个解析sheet的线程处理得比较慢,我们不可能让主线程一直等待,所以可以使用另外一个带指定时间的await()方法,这个方法等待特定时间之后就会不再阻塞当前线程。join也有类似方法。

await(long time, TimeUnit unit);//在特定时间之后就不会阻塞当前线程

8.2 同步屏障 CyclicBarrier

CyclicBarrier 表可循环使用的屏障。其做的事情是,让一组线程到达一个屏障(同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续运行。

8.2.1 CyclicBarrier简介

CyclicBarrier 的构造方法是 CyclicBarrier(int parties),其参数表示屏障拦截的线程数量,每个线程调用await()方法告诉 CyclicBarrier 我已经到达屏障,然后当前线程被阻塞

CyclicBarrier(int parties);//参数表示屏障拦截的线程数量

8.2.2 CyclicBarrier 应用场景

CyclicBarrier 可用于多线程计算数据,最后合并计算结果的场景。

8.2.3 CyclicBarrier 和 CountDownLatch 的区别

CountDownLatch 的计数器只能使用一次,而 CyclicBarrier 的计数器可以使用reset()方法重置。

8.3 控制并发线程数的Semaphore

Semaphore (信号量)是用来控制同时访问特定资源的线程数量,通过协调各个线程,以保证合理的使用公共资源。

信号量可以指定多个线程同时访问某一个资源。提供构造函数:

1. public Semaphore(int permits);

2. public Semaphore(int permits, boolean fair);//fair指是否是公平锁

在构造信号量对象时应该指定信号量的准入数,即能够同时申请多少个许可。当每个线程每次只申请一个许可时,这就相当于指定了同时有多少个线程可以访问某一个资源。

1. public void acquire();

2. public void acquireUninterruptibly();//不响应中断

3. public boolean tryAcquire();//获取一个许可

4. public boolean tryAcquire(long timeout, TimeUnit unit);

5. public void release();

8.3.1 应用场景

Semaphore 可以用作流量控制,特别是公用资源有限的应用场景。

8.3.2 其它方法

1. int availablePermits() 返回此信号量当前可用的许可证数量

2. int getQueueLength() 返回正在等待获取许可证的线程数

3. boolean hasQueueThreads() 是否有线程正在等待获取许可证

4. void reducePermits(int reduction) 减少reduction个许可证

5. Collection getQueuedThread() 返回所有等待获取许可证的线程集合

8.4 线程间交换数据的Exchanger

Exchanger 是一个用于线程间协作的工具类。Exchanger用于进行线程间的数据交换。它提供一个同步点,在这个同步点,两线程可以交换彼此的数据。

如果一个线程先执行exchange()方法,它会一直等待第二个线程也执行exchange()方法,当两个线程都到达同步点时,这两个线程可以交换数据,将本线程生产出来的数据传递给对方。

8.5 线程阻塞工具类 LockSupport

线程阻塞工具类 LockSupport 是一个实用的工具类,可以在线程任意位置让线程阻塞。与Thread.suspend()方法比较,弥补了resume()方法发生导致线程无法继续执行的情况。

线程阻塞工具类 LockSupport 的静态方法 park() 方法阻塞当前线程,类似的还有 parkNanos() | parkUntil()等方法,其实现了一个限时等待。

本文标题:并发工具类

文章作者:Bangjin-Hu

发布时间:2019年10月15日 - 09:22:26

最后更新:2020年03月30日 - 08:18:41

原始链接:http://bangjinhu.github.io/undefined/第8章 Java中的并发工具类/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

Bangjin-Hu wechat
欢迎扫码关注微信公众号,订阅我的微信公众号.
坚持原创技术分享,您的支持是我创作的动力.