Java 并发系列之八:java 并发工具(4个)
1. CountDownLatch
2. CyclicBarrier
3. Semaphore
4. Exchanger
5. txt
1 java 并发工具 2 通俗理解 3 CountDownLatch 4 等ABCD 4个人都结束了,自己才能开始,结束一个减一个 5 CyclicBarrier 6 我和A,B,C,D 5个人互相等待,会合了再一起进电影院,到一个减一个 7 Semaphore 8 计数器,鸡蛋篮子里只能放5个鸡蛋,缺几个,才能放几个 9 Exchanger 10 A和B交换数据 11 CountDownLatch 12 CountDownLatch 它允许一个或多个线程等待其他N个指定数量线程完成操作 13 CountDownLatch也可以实现join的功能,并且比join的功能更多 14 AQS(队列同步器) 共享锁 15 内部类 16 sync为CountDownLatch的一个内部类,而Sync继承AQS。 17 采用共享锁来实现的。 18 重要操作 19 CountDownLatch(int count) 20 构造一个用给定计数初始化的 CountDownLatch,count为计数器的初始值,也可以理解为该共享锁可以获取的总次数。 21 await() 22 使当前线程在锁存器倒计数至零之前一直等待,除非线程被中断 23 awit(long time, TimeUnit unit) 24 带指定时间的await方法,这个方法在等待特定时间之后,就不会阻塞当前线程。 25 countDown() 26 递减锁存器的计数,如果计数到达零,则释放所有等待的线程。 27 一个线程调用countDown方法 happen-before 另外一个线程调用 await 方法 28 注意CountDownLatch不能回滚重置。 29 CyclicBarrier 30 定义 31 可循环使用的同步屏障:它允许一组线程互相等待,直到达到某个公共屏障点(common barrier point) 32 通俗讲:让一组线程到达一个屏障是被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续干活 33 底层采用ReentrantLock + Condition 实现 34 重要操作 35 两个构造函数 36 CyclicBarrier(int parties):parties表示屏障拦截的线程数量(插入的屏障数),每个线程调用await方法告诉CyclicBarrier已经到达了屏障,然后当前线程被阻塞。 37 CyclicBarrier(int parties, Runnable barrierAction) :用于在线程到达屏障前,优先执行barrierAction,方便处理更复杂的业务场景 38 其他方法 39 getNumberWaiting 40 获得CyclicBarrier阻塞的线程数量 41 isBrocken 42 了解阻塞的线程是否被中断 43 await() 44 插入屏障,到达了屏障,本质上相当于屏障数-1 45 应用场景 46 多线程结果合并的操作,用于多线程计算数据,最后合并计算结果的应用场景 47 CyclicBarrier V.S. CountDownLatch 48 CountDownLatch的作用是允许1个或N个线程等待其他线程完成执行; 49 CyclicBarrier则是允许N各线程互相等待 50 CountDownLatch的计数器无法被重置,只能使用一次如果需要重置计数,请考虑使用CyclicBarrier. 51 CyclicBarrier的计数器可以被reset重置后使用,因此它被称为是循环的barrier,能处理更为复杂的业务场景。例如计算发生错误,可以重置计数器,并让线程重新执行一次 52 Semaphore 53 信号量 54 计数器,用来控制同时访问特定资源的线程数量,他通过协调各个线程,以保证合理的使用公共资源 55 内部采用共享锁实现 56 信号量Semaphore是一个非负数(>=1)。当一个线程想要访问某个共享资源时,它必须要先获取Semaphore,当Semaphore>0 时,获取该资源并使 Semaphore-1. 如果Semaphore=0,则表示全部的共享资源已经被其他线程全部占用,线程必须要等待其他线程释放资源。当线程释放资源时,Semaphore+1。 57 从概念上讲,信号量维护了一个许可集。如有必要,在许可可用前会阻塞每一个acquire(),然后再获取该许可。每个release()添加一个许可,从而可能释放一个正在阻塞的获取者。但是,不使用实际的许可对象,Semaphore只对许可的号码进行计数,并采取相应的行动。 58 重要操作 59 Semaphore(int permits) 60 构造函数,接受一个整型的数字,表示可用的许可证数量,也就是最大的并发量 61 acquire 62 获取一个许可证 63 tryAcquire 64 尝试获取一个许可证 65 release 66 归还许可证 67 int availablePermits() 68 返回此信号量中当前可用的许可证数 69 int getQueueLength() 70 返回正在等待获取许可证的线程数 71 boolean hasQueuedThreads() 72 是否有线程正在等待获取许可证 73 void reducePermits(int reduction) 74 减少reduction个许可证 75 Collection getQueuedThreads() 76 返回所有等待获取许可证的线程集合 77 应用场景 78 用于流量控制,特别是公用资源有限的应用场景,比如数据库连接。 79 Exchanger 80 定义 81 交换者,是一个用于线程间协作的工具类,用于进行线程间的数据交换,两个线程 82 它提供一个同步点,用于进行线程间成对配对及交换数据, 83 具体 84 第一个线程先执行exchange()方法,它会一只等待第二个线程也执行exchange()方法,当两个线程都到达同步点时,两个线程就可以交换数据,将本线程生产出来的数据传递给对方 85 允许在并发任务之间交换数据。具体来说,Exchanger类允许在两个线程之间定义同步点。当两个线程都到达同步点时,他们交换数据结构,因此第一个线程的数据结构进入到第二个线程中,第二个线程的数据结构进入到第一个线程中 86 应用场景 87 遗传算法 88 交叉 89 校对工作 90 AB岗录入电子银行流水 91 Exchanger 可能被视为 SynchronousQueue 的双向形式。Exchanger 可能在应用程序(比如遗传算法和管道设计)中很有用。