CountDownLatch 执行 - - 操作
允许一个或多个线程等待直到在其他线程中执行的一组操作完成的同步辅助。
CountDownLatch用给定的计数初始化。 await方法阻塞,直到由于countDown()方法的调用而导致当前计数达到零,之后所有等待线程被释放,并且任何后续的await 调用立即返回。 这是一个一次性的现象 - 计数无法重置
底层使用队列。
public CountDownLatch(int count) {
if (count < 0) throw new IllegalArgumentException("count < 0");
this.sync = new Sync(count);
}
public void countDown() {
sync.releaseShared(1);
}
public void await() throws InterruptedException {
sync.acquireSharedInterruptibly(1);
}
由于底层使用的队列,当调用一次countDown()方法,一个 线程出去
调用await()方法,如果线程队列中部位空,则等待,只有当线程队列中为空才能往下执行await()之后的代码。
public class CountDownLatchDemo {
public static void main(String[] args) throws InterruptedException {
CountDownLatch latch = new CountDownLatch(5);
for (int i = 1; i <= 5; i++) {
new Thread(()->{
System.out.println(Thread.currentThread().getName()+"\t离开教室-----");
latch.countDown();
},StudentEnum.forStudentEnum(i).getRetMessage()).start();;
}
latch.await();
System.out.println("班长锁门!!!");
}
}
CyclicBarrier
允许一组线程全部等待彼此达到共同屏障点的同步辅助。 循环阻塞在涉及固定大小的线程方的程序中很有用,这些线程必须偶尔等待彼此。
public CyclicBarrier(int parties,Runnable barrierAction)
parties - 屏障跳闸前必须调用 await()的线程数
barrierAction - 当屏障跳闸时执行的命令,或 null如果没有动作
例如:七龙珠中收集龙珠的操作,只有当所有龙珠都收集完成才能召唤神龙
package interview_3;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierDemo {
public static void main(String[] args) {
//public CyclicBarrier(int parties,Runnable barrierAction)
//parties - 屏障跳闸前必须调用 await()的线程数
// barrierAction - 当屏障跳闸时执行的命令,或 null如果没有动作
CyclicBarrier barrier = new CyclicBarrier(7,
()->{System.out.println("**********************召唤神龙");});
for (int i = 1; i <= 7; i++) {
new Thread(()->{
System.out.println("第"+Thread.currentThread().getName()+"颗龙珠被收集");
try {
barrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
},String.valueOf(i)).start();;
}
}
}
Semaphore 信号量机制
例如 PV操作 P占用资源 资源-1 V释放资源 资源+1;
例如:停车场停车问题
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
/**
* 信号量机制
* @author yezhiming
*2019年9月16日
*@version
*/
public class SemaphoreDemo {
public static void main(String[] args) {
//初始化信号量资源 3个停车位
Semaphore semaphore = new Semaphore(3);
for (int i = 1; i <= 8; i++) {
new Thread(()->{
try {
semaphore.acquire();
System.out.println(Thread.currentThread().getName()+"进入了停车场");
TimeUnit.SECONDS.sleep(2);
System.out.println(Thread.currentThread().getName()+"停了2S 后离开");
} catch (Exception e) {
e.printStackTrace();
}finally{
semaphore.release();
}
},String.valueOf(i)).start();;
}
}
}