java.util.concurrent(J.U.C)大大提高了并发性能,AQS 被认为是 J.U.C 的核心。

CountdownLatch

用来控制一个线程等待多个线程。

维护了一个计数器 cnt,每次调用 countDown() 方法会让计数器的值减 1,减到 0 的时候,那些因为调用 await() 方法而在等待的线程就会被唤醒。

public class CountdownLatchExample {

    public static void main(String[] args) throws InterruptedException {
final int totalThread = 10;
CountDownLatch countDownLatch = new CountDownLatch(totalThread);
ExecutorService executorService = Executors.newCachedThreadPool();
for (int i = 0; i < totalThread; i++) {
executorService.execute(() -> {
System.out.print("run..");
countDownLatch.countDown();
});
}
countDownLatch.await();
System.out.println("end");
executorService.shutdown();
}
}
run..run..run..run..run..run..run..run..run..run..end
 

CyclicBarrier

用来控制多个线程互相等待,只有当多个线程都到达时,这些线程才会继续执行。

和 CountdownLatch 相似,都是通过维护计数器来实现的。线程执行 await() 方法之后计数器会减 1,并进行等待,直到计数器为 0,所有调用 await() 方法而在等待的线程才能继续执行。

CyclicBarrier 和 CountdownLatch 的一个区别是,CyclicBarrier 的计数器通过调用 reset() 方法可以循环使用,所以它才叫做循环屏障。

CyclicBarrier 有两个构造函数,其中 parties 指示计数器的初始值,barrierAction 在所有线程都到达屏障的时候会执行一次。

public CyclicBarrier(int parties, Runnable barrierAction) {
if (parties <= 0) throw new IllegalArgumentException();
this.parties = parties;
this.count = parties;
this.barrierCommand = barrierAction;
} public CyclicBarrier(int parties) {
this(parties, null);
}

public class CyclicBarrierExample {

    public static void main(String[] args) {
final int totalThread = 10;
CyclicBarrier cyclicBarrier = new CyclicBarrier(totalThread);
ExecutorService executorService = Executors.newCachedThreadPool();
for (int i = 0; i < totalThread; i++) {
executorService.execute(() -> {
System.out.print("before..");
try {
cyclicBarrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
System.out.print("after..");
});
}
executorService.shutdown();
}
}
before..before..before..before..before..before..before..before..before..before..after..after..after..after..after..after..after..after..after..after..
 

Semaphore

Semaphore 类似于操作系统中的信号量,可以控制对互斥资源的访问线程数。

以下代码模拟了对某个服务的并发请求,每次只能有 3 个客户端同时访问,请求总数为 10。

public class SemaphoreExample {

    public static void main(String[] args) {
final int clientCount = 3;
final int totalRequestCount = 10;
Semaphore semaphore = new Semaphore(clientCount);
ExecutorService executorService = Executors.newCachedThreadPool();
for (int i = 0; i < totalRequestCount; i++) {
executorService.execute(()->{
try {
semaphore.acquire();
System.out.print(semaphore.availablePermits() + " ");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
semaphore.release();
}
});
}
executorService.shutdown();
}
}
2 1 2 2 2 2 2 1 2 2

免费Java高级资料需要自己领取,涵盖了Java、Redis、MongoDB、MySQL、Zookeeper、Spring Cloud、Dubbo高并发分布式等教程,一共30G。
传送门:https://mp.weixin.qq.com/s/JzddfH-7yNudmkjT0IRL8Q

最新文章

  1. PBR实现
  2. 挖一挖C#中那些我们不常用的东西之系列(2)——IsXXX 系列方法
  3. 对setTimeout()第一个参数是字串的深入理解以及eval函数的理解
  4. 虚拟主机apache
  5. Class.forName()的理解
  6. Traceroute程序
  7. Nginx 和 IIS 实现动静分离【转载】
  8. AI类人工智能产品经理的丛林法则
  9. awk多分隔符功能及wc命令案列及企业级应用
  10. js数组去重排序(封装方法)
  11. mysql null 相关bug
  12. Module 的语法
  13. Android使用ViewPager+PhotoView实现图片查看器
  14. 【php】随缘php企业网站管理系统V2.0 shownews.php注入漏洞
  15. Java并发编程基础-ReentrantLock的机制
  16. 【Python】解析Python的缩进规则
  17. oracle数据库创建分区表
  18. ie6定位absolute bug触发layout解决
  19. 简单实现http proxy server怎么实现?
  20. 如何使用 Chrome 浏览器调试动态加载的 Javascript 脚本

热门文章

  1. 批处理文件执行cmd命令
  2. HDU 5739 Fantasia 双连通分量 树形DP
  3. “帮你APP”团队冲刺4
  4. 66、fastJson 解析json数据时,如果key值不同怎么处理?
  5. adb命令模拟按键事件
  6. Google&#160;Chrome开发者工具-移动仿真:触摸事件仿真
  7. 16进制转10进制 HDU-1720
  8. Leetcode 650.只有两个键的键盘
  9. pandas神坑:如果列有NAN,则默认给数据转换为float类型!给pandas列指定不同的数据类型。
  10. leetcode NO.7 反转整数 (python实现)