CountDownLatch类
-
功能:判断count计数不为0时,则当前线程呈wait状态,也就是在屏障处等待。
-
使用效果:判断count计数不为0时,则线程呈wait状态;如果count计数为0,则线程继续运行。
-
重要API
3-0:CountDownLatch(int count) 构造方法指定count数 3-1:await()方法:判断计数是否为0;若不为0,则等待;若为0,则执行 3-2:countDown()方法:线程调用,则计数减1; 3-3:getCount()方法:获得当前的计数个数。 3-4:await(long timeout,TimeUnit unit)方法:与await()功能一样,只是,当超过timeout后,会自动唤醒,往下执行。
-
计数是无法重置的,CountDownLatch是减法计数,若要重置,考虑 CyclicBarrier类
-
例子:元件生产和组装
5-1:ThreadA(组装线程类)
package com.countDownLatchA;
import java.util.concurrent.CountDownLatch;
public class ThreadA extends Thread {
private CountDownLatch countDownLatch;
public ThreadA(CountDownLatch countDownLatch) {
this.countDownLatch = countDownLatch;
}
@Override
public void run() {
super.run();
try {
System.out.println(getName()+":开始等待其他工序");
countDownLatch.await();
System.out.println(getName()+":其他工序完成");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
5-2:ThreadB(元件生产类)
package com.countDownLatchA;
import java.util.concurrent.CountDownLatch;
public class ThreadB extends Thread {
private CountDownLatch countDownLatch;
public ThreadB(CountDownLatch countDownLatch) {
this.countDownLatch = countDownLatch;
}
@Override
public void run() {
super.run();
countDownLatch.countDown();
System.out.println(getName()+":工序已完成还剩下"+countDownLatch.getCount()+"道工序");
}
}
5-3:App类(执行类)
package com.countDownLatchA;
import java.util.concurrent.CountDownLatch;
public class App {
public static void main(String[] args){
CountDownLatch countDownLatch=new CountDownLatch(5);
ThreadA threadA=new ThreadA(countDownLatch);
ThreadB[] threadB=new ThreadB[5];
threadA.setName("组装工序");
for (int i = 0; i <5 ; i++) {
threadB[i] = new ThreadB(countDownLatch);
threadB[i].setName("元件"+(i+1)+"生产");
}
threadA.start();
for (int i = 0; i <threadB.length ; i++) {
threadB[i].start();
}
}
}
5-4:运行结果
CyclicBarrier类
-
功能:多线程相互等待,任何一个线程完成之前,所有的线程都必须等待;
-
与CountDownLatch的区别:CyclicBarrier是同类互相等待;CountDownLatch是两个角色互相等待
-
API:
3-1:构造方法 1. CyclicBarrier(int parties): 创建一个CyclicBarrier,并指定障碍数量parties 2. CyclicBarrier(int parties, Runnable barrierAction) :用于线程到达屏障(越过Parties个屏障后)时,优先执行barrierAction。 3-2:成员方法 1. getNumberWaiting() :获取正在CyclicBarrier上等待的线程数量。 2. getParties():获取cyclicBarrier的障碍总数(parties值) 3. await():在CyclicBarrier上进行阻塞等待,直到发生以下情形之一: 3-1:在CyclicBarrier上等待的线程数量达到parties,则所有线程被释放,继续执行。 3-2:当前线程被中断,则抛出InterruptedException异常,并停止等待,继续执行。 3-3:其他等待的线程被中断,则当前线程抛出BrokenBarrierException异常,并停止等待,继续执行。 3-4:其他等待的线程超时,则当前线程抛出BrokenBarrierException异常,并停止等待,继续执行。 3-5:其他线程调用CyclicBarrier.reset()方法,则当前线程抛出BrokenBarrierException异常,并停止等待,继续执行。 4. await(timeout,TimeUnit):在CyclicBarrier上进行限时的阻塞等待,直到发生以下情形之一: 4-1:在CyclicBarrier上等待的线程数量达到parties,则所有线程被释放,继续执行。 4-2:当前线程被中断,则抛出InterruptedException异常,并停止等待,继续执行。 4-3:当前线程等待超时,则抛出TimeoutException异常,并停止等待,继续执行。 4-4:其他等待的线程被中断,则当前线程抛出BrokenBarrierException异常,并停止等待,继续执行。: 4-5:其他等待的线程超时,则当前线程抛出BrokenBarrierException异常,并停止等待,继续执行。 4-5其他线程调用CyclicBarrier.reset()方法,则当前线程抛出BrokenBarrierException异常,并停止等待,继续执行。 5. isBroken()获取是否破损标志位broken的值,此值有以下几种情况: 5-1:CyclicBarrier初始化时,broken=false,表示屏障未破损。 5-2:如果正在等待的线程被中断,则broken=true,表示屏障破损。 5-3:如果正在等待的线程超时,则broken=true,表示屏障破损。 5-4:如果有线程调用CyclicBarrier.reset()方法,则broken=false,表示屏障回到未破损状态。 6. reset():使得CyclicBarrier回归初始状态,直观来看它做了两件事: 6-1:如果有正在等待的线程,则会抛出BrokenBarrierException异常,且这些线程停止等待,继续执行。将是否破损标志位broken置为false。