1 CountDownLatch
其实就是一个减法计数器,对于计数器归零之后再进行后面的操作,这是一个计数器!
//这是一个计数器 减法
public class CountDownLatchDemo {
public static void main(String[] args) throws InterruptedException {
//总数是6
CountDownLatch countDownLatch = new CountDownLatch(6);
for (int i = 1; i <= 6 ; i++) {
new Thread(()->{
System.out.println(Thread.currentThread().getName()+" Go out");
countDownLatch.countDown(); //每个线程都数量-1
},String.valueOf(i)).start();
}
countDownLatch.await(); //等待计数器归零 然后向下执行
System.out.println("close door");
}
}
主要方法:
- countDown 减一操作;
- await 等待计数器归零。
await等待计数器为0,就唤醒,再继续向下运行。
2 CyclickBarrier
其实就是一个加法计数器;
public class CyclicBarrierDemo {
public static void main(String[] args) {
//主线程
CyclicBarrier cyclicBarrier = new CyclicBarrier(7,()->{
System.out.println("召唤神龙~");
});
for (int i = 1; i <= 7; i++) {
//子线程
int finalI = i;
new Thread(()->{
System.out.println(Thread.currentThread().getName()+" 收集了第 {"+ finalI+"} 颗龙珠");
try {
cyclicBarrier.await(); //加法计数 等待
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}).start();
}
}
}
lambda表达式只能用final类型
3 Semaphore
public class SemaphoreDemo {
public static void main(String[] args) {
//停车位为3个
Semaphore semaphore = new Semaphore(3);
for (int i = 1; i <= 6; i++) {
int finalI = i;
new Thread(()->{
try {
semaphore.acquire(); //得到
//抢到车位
System.out.println(Thread.currentThread().getName()+" 抢到了车位{"+ finalI +"}");
TimeUnit.SECONDS.sleep(2); //停车2s
System.out.println(Thread.currentThread().getName()+" 离开车位");
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
semaphore.release();//释放
}
},String.valueOf(i)).start();
}
}
}
原理:
-
semaphore.acquire()获得资源,如果资源已经使用完了,就等待资源释放后再进行使用!
-
semaphore.release()释放,会将当前的信号量释放+1,然后唤醒等待的线程!
作用: 多个共享资源互斥的使用! 并发限流,控制最大的线程数!