参考
描述(JDK文档内容)
-
CountDownLatch 减法计数器:允许一个或多个线程等待直到在其他线程中执行的一组操作完成的同步辅助。(通过 countDow() 方法进行减少计数,当计数为0时 await 处会被唤醒)
- 构造方法 :
CountDownLatch(int count) 构造一个用给定计数初始化的 CountDownLatch
countDown() :减少锁存器的计数,如果计数达到零则释放所有等待的线程
await():导致当前线程等到锁存器倒计数到零,除非线程是 interrupted
-
CyclicBarrier 加法计数器:一种同步辅助工具,允许一组线程全部等待彼此到达公共障碍点。(通过 await() 方法进行增加计数,当计数为 parties 时执行 barrierAction 代码。)
CyclicBarrier(int parties, Runnable barrierAction):创建一个新的 CyclicBarrier ,当给定数量的参与方(线程)等待它时将跳闸,并且当屏障被触发时执行给定的屏障操作,由进入屏障的最后一个线程执行。(有两个构造方法,第一个构造方法可以不传入 Runnable/Lambda,而不执行指定操作 )
await():等待所有 parties 在此障碍上调用 await 。
reset():将屏障重置为其初始状态。
-
Semaphore 信号量:计数信号量。 从概念上讲,信号量保持一组许可。 如果有必要,每个 acquire() 都会阻止,直到有许可证,然后接受。 每个 release() 都添加了许可证,可能会释放阻止收购者。 但是,没有使用实际的许可对象; Semaphore 只保留可用数量并相应地采取行动。(通过 acquire 获取一个执行许可,当执行许可被授权完毕之后,后面还需要获取授权的线程会堵塞并等待;当线程执行完毕后,通过 release 归还许可。)
Semaphore(int permits):使用给定数量的许可和非公平公平设置创建 Semaphore 。(第二个构造方法需要传入一个参数来设置 是否公平锁,默认不传入是非公平锁)
acquire():从此信号量获取许可,阻止直到一个可用,或者线程为 interrupted 。
release():发布许可证,将其返回到信号量。
代码(狂神说代码)
package thread;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
/**
* @Author 夏秋初
* @Date 2022/3/1 15:36
*/
public class Test {
public static void main(String[] args) throws InterruptedException {
// 减法计数器,初始化参数为设置计数次数
CountDownLatch countDownLatch = new CountDownLatch(10);
//
for (int i = 0; i < 10; i++) {
new Thread(()->{
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"执行完毕");
// 计数减一
countDownLatch.countDown();
}, String.valueOf(i)).start();
}
// 计数器清零前不会结束
countDownLatch.await();
System.out.println("程序加载完毕");
}
}
package thread;
import java.util.*;
import java.util.concurrent.*;
/**
* @Author 夏秋初
* @Date 2022/3/1 15:36
*/
public class Test {
public static void main(String[] args) throws InterruptedException {
// 加法计数器
CyclicBarrier cyclicBarrier = new CyclicBarrier(10, ()->{
System.out.println("程序执行完毕");
});
//
for (int i = 0; i < 10; i++) {
new Thread(()->{
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"执行完毕");
// 计数加一
try {
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}, String.valueOf(i)).start();
}
}
}
package thread;
import java.util.*;
import java.util.concurrent.*;
/**
* @Author 夏秋初
* @Date 2022/3/1 15:36
*/
public class Test {
public static void main(String[] args) throws InterruptedException {
// 限流
Semaphore semaphore = new Semaphore(2);
//
for (int i = 0; i < 10; i++) {
new Thread(()->{
try {
semaphore.acquire();
System.out.println(Thread.currentThread().getName()+"执行完毕");
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
semaphore.release();
}
}, String.valueOf(i)).start();
}
}
}