一、CyclicBarrier

作用:所有线程准备好才进行,只要一条线程没准备好,都不进行

用法:所有线程准备好以后调用CyclicBarrier的await方法,然后主线程执行CyclicBarrier的countDown方法

实现需求:n个运动员(n个线程),全部准备好了才一起起跑。代码如下

 1 package concurrent019;
2 import java.io.IOException;
3 import java.util.Random;
4 import java.util.concurrent.BrokenBarrierException;
5 import java.util.concurrent.CyclicBarrier;
6 import java.util.concurrent.ExecutorService;
7 import java.util.concurrent.Executors;
8 public class UseCyclicBarrier {
9
10 static class Runner implements Runnable {
11 private CyclicBarrier barrier;
12 private String name;
13
14 public Runner(CyclicBarrier barrier, String name) {
15 this.barrier = barrier;
16 this.name = name;
17 }
18 @Override
19 public void run() {
20 try {
21 Thread.sleep(1000 * (new Random()).nextInt(5));
22 System.out.println(name + " 准备OK.");
23 barrier.await();
24 } catch (InterruptedException e) {
25 e.printStackTrace();
26 } catch (BrokenBarrierException e) {
27 e.printStackTrace();
28 }
29 System.out.println(name + " Go!!");
30 }
31 }
32
33 public static void main(String[] args) throws IOException, InterruptedException {
34 CyclicBarrier barrier = new CyclicBarrier(3); // 3
35 ExecutorService executor = Executors.newFixedThreadPool(3);
36
37 executor.submit(new Thread(new Runner(barrier, "zhangsan")));
38 executor.submit(new Thread(new Runner(barrier, "lisi")));
39 executor.submit(new Thread(new Runner(barrier, "wangwu")));
40
41 executor.shutdown();
42 }
43
44 }
 

二、CountDownLacth

作用:监听某些初始化操作,等初始化执行完毕以后,通知主线程继续工作(例如zk的初始化)

用法:将需要别的线程来通知的线程调用CountDownLacth的await方法,其他线程执行了之后,允许这个线程执行的时候,执行CountDownLacth的countDown方法

实现需求:启动3个线程,1线程等待2和3线程执行完毕以后再执行,代码如下:

 1 package concurrent019;
2
3 import java.util.concurrent.CountDownLatch;
4
5 public class UseCountDownLatch {
6
7 public static void main(String[] args) {
8
9 final CountDownLatch countDown = new CountDownLatch(2);
10
11 Thread t1 = new Thread(new Runnable() {
12 @Override
13 public void run() {
14 try {
15 System.out.println("进入线程t1" + "等待其他线程处理完成...");
16 countDown.await();
17 System.out.println("t1线程继续执行...");
18 } catch (InterruptedException e) {
19 e.printStackTrace();
20 }
21 }
22 },"t1");
23
24 Thread t2 = new Thread(new Runnable() {
25 @Override
26 public void run() {
27 try {
28 System.out.println("t2线程进行初始化操作...");
29 Thread.sleep(3000);
30 System.out.println("t2线程初始化完毕,通知t1线程继续...");
31 countDown.countDown();
32 } catch (InterruptedException e) {
33 e.printStackTrace();
34 }
35 }
36 });
37 Thread t3 = new Thread(new Runnable() {
38 @Override
39 public void run() {
40 try {
41 System.out.println("t3线程进行初始化操作...");
42 Thread.sleep(4000);
43 System.out.println("t3线程初始化完毕,通知t1线程继续...");
44 countDown.countDown();
45 } catch (InterruptedException e) {
46 e.printStackTrace();
47 }
48 }
49 });
50
51 t1.start();
52 t2.start();
53 t3.start();
54
55 }
56 }

ps:CyclicBarrier和CountDownLacth的区别

CyclicBarrier是所有线程等待一个线程的信号,CountDownLacth是一个线程等待所有线程的信号

三、Callable、Future

Future实现的就是前面讲的Future模式.

实现功能:主线程在执行的过程中,调用了一个或者多个耗时的操作,需要把这个耗时的操作提到另几个线程操作(这几个耗时的操作可以并行执行)

代码实现:

 1 package concurrent019;
2
3 import java.util.concurrent.Callable;
4 import java.util.concurrent.ExecutorService;
5 import java.util.concurrent.Executors;
6 import java.util.concurrent.FutureTask;
7
8 public class UseFuture implements Callable<String>{
9 private String para;
10
11 public UseFuture(String para){
12 this.para = para;
13 }
14
15 /**
16 * 这里是真实的业务逻辑,其执行可能很慢
17 */
18 @Override
19 public String call() throws Exception {
20 //模拟执行耗时
21 Thread.sleep(3000);
22 String result = this.para + "处理完成";
23 return result;
24 }
25
26 //主控制函数
27 public static void main(String[] args) throws Exception {
28 String queryStr = "query";
29 //构造FutureTask,并且传入需要真正进行业务逻辑处理的类,该类一定是实现了Callable接口的类
30 FutureTask<String> future = new FutureTask<String>(new UseFuture(queryStr));
31 //创建一个固定线程的线程池且线程数为1,
32 ExecutorService executor = Executors.newFixedThreadPool(1);
33 //这里提交任务future,则开启线程执行RealData的call()方法执行
34 executor.submit(future);
35 System.out.println("请求完毕");
36 try {
37 //这里可以做额外的数据操作,也就是主程序执行其他业务逻辑
38 Thread.sleep(2000);
39 } catch (Exception e) {
40 e.printStackTrace();
41 }
42 //调用获取数据方法,如果call()方法没有执行完成,则依然会进行等待
43 System.out.println("数据:" + future.get()); // 其实这块应该开启线程处理
44 executor.shutdown();
45 }
46
47 }

四、Semaphore(信号量)

Semaphore是计数信号量。Semaphore管理一系列许可证。每个acquire方法阻塞,直到有一个许可证可以获得然后拿走一个许可证;每个release方法增加一个许可证,这可能会释放一个阻塞的acquire方法。然而,其实并没有实际的许可证这个对象,Semaphore只是维持了一个可获得许可证的数量。(用于限流)

实现需求:总共有20条线程,但是最多只能放5条线程进来执行

代码实例:

 1 package concurrent019;
2
3 import java.util.concurrent.ExecutorService;
4 import java.util.concurrent.Executors;
5 import java.util.concurrent.Semaphore;
6
7 public class UseSemaphore {
8
9 public static void main(String[] args) {
10 // 线程池
11 ExecutorService exec = Executors.newCachedThreadPool();
12 // 只能5个线程同时访问
13 final Semaphore semp = new Semaphore(5);
14 // 模拟20个客户端访问
15 for (int index = 0; index < 20; index++) {
16 final int NO = index;
17 Runnable run = new Runnable() {
18 public void run() {
19 try {
20 // 获取许可
21 semp.acquire();
22 System.out.println("Accessing: " + NO);
23 //模拟实际业务逻辑
24 Thread.sleep((long) (Math.random() * 10000));
25 // 访问完后,释放
26 semp.release();
27 } catch (InterruptedException e) {
28 }
29 }
30 };
31 exec.execute(run);
32 }
33
34 try {
35 Thread.sleep(10);
36 } catch (InterruptedException e) {
37 e.printStackTrace();
38 }
39
40 //System.out.println(semp.getQueueLength());
41
42
43
44 // 退出线程池
45 exec.shutdown();
46 }
47
48 }

java并发包工具(java.util.Concurrent)的更多相关文章

  1. 八、jdk工具之JvisualVM、JvisualVM之二--Java程序性能分析工具Java VisualVM

    目录 一.jdk工具之jps(JVM Process Status Tools)命令使用 二.jdk命令之javah命令(C Header and Stub File Generator) 三.jdk ...

  2. Java反编译工具(Java Decompiler)

    Java Decompiler是一种非常实用的JAVA反编译工具,可以对整个jar包进行反编译,也可以将其集成到eclipse上,非常方便的根据class文件的源码.,官网地址http://jd.be ...

  3. Java程序性能分析工具Java VisualVM(Visual GC)—程序员必备利器

    VisualVM 是一款免费的\集成了多个JDK 命令行工具的可视化工具,它能为您提供强大的分析能力,对 Java 应用程序做性能分析和调优.这些功能包括生成和分析海量数据.跟踪内存泄漏.监控垃圾回收 ...

  4. Java静态检测工具/Java代码规范和质量检查简单介绍(转)

    静态检查: 静态测试包括代码检查.静态结构分析.代码质量度量等.它可以由人工进行,充分发挥人的逻辑思维优势,也可以借助软件工具自动进行.代码检查代码检查包括代码走查.桌面检查.代码审查等,主要检查代码 ...

  5. 201671010133 2016-2017-2 《java程序设计》 初学java!

    新学期伊始,我心中既充满了期待和希望,又有些许激动和感慨.期待的是即将接触许多新的知识,期待未来比过去过的更加踏实有趣,期待遇到更好的人和事等等.当然,面对从未了解过的新事物时,我想每个人的想法都大致 ...

  6. java CountDownLatch报错java.lang.IllegalMonitorStateException: null

    笔者使用websocket进行通信,服务器异步返回.websocket服务器又异步调用其他websocket,也是异步访问. 由于无法预测服务器调用第三方websocket什么时候调用结束,使用了Co ...

  7. netty-websocket-spring-boot-starter关闭报错 io/netty/channel/AbstractChannel$AbstractUnsafe io/netty/util/concurrent/GlobalEventExecutor

    报错 java.lang.NoClassDefFoundError: io/netty/channel/AbstractChannel$AbstractUnsafe$ at io.netty.chan ...

  8. Java并发—java.util.concurrent并发包概括(转载)

    一.描述线程的类:Runable和Thread都属于java.lang包 二.内置锁synchronized属于jvm关键字,内置条件队列操作接口Object.wait()/notify()/noti ...

  9. java.util.concurrent中的几种同步工具类

    java.util.concurrent并发包中提供了一系列的的同步工具类,这些基础类不管是否能在项目中使用到,了解一下使用方法和原理对java程序员来说都是有必要的.博主在看<java并发编程 ...

随机推荐

  1. springboot多模块项目搭建遇到的问题记录

    废话不多说,直接上问题报错与解决方法. 问题报错一:(报错信息看下方代码) 问题原因:'com.company.logistics.service.company.CompanyService' 未找 ...

  2. PyQt(Python+Qt)学习随笔:键盘焦点和逻辑焦点(Logic Focus与Keyboard Focus )

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 Qt中的焦点有键盘焦点和逻辑焦点(Logic Focus与Keyboard Focus )的区分,键 ...

  3. 性能测试学习之路 (四)jmeter 脚本开发实战(JDBC &JMS &接口脚本 & 轻量级接口自动化测试框架)

    1.业务级脚本开发 登录脚本->思路:在线程组下新建两个HTTP请求,一个是完成访问登录页,一个是完成登录的数据提交.   步骤如下: 1) 访问登录页 2) 提交登录数据的HTTP PS:对于 ...

  4. 哀悼疫情,全站灰色如何实现,CSS滤镜一行代码实现

    庚子清明,以国家之名哀悼,以国家之名哀悼在新冠肺炎疫情中牺牲的烈士和逝世的同胞! 向抗疫英雄致敬! 今日打开各样的app,各大电商,爱奇艺都是灰色的 这里我也一直很好奇该功能,前端如何实现,了解过后发 ...

  5. Springboot — 用更优雅的方式发HTTP请求:RestTemplate

    RestTemplate是Spring提供的用于访问Rest服务的客户端,RestTemplate提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效率. 我之前的HTTP开发是用ap ...

  6. 汉化gitlab

    一.,基于 Larry Li 版汉化指南 修改 (以9-0-stable-zh分支为例) 源码安装汉化 推荐按照 gitlab-ce 源代码中 doc/install/installation.md ...

  7. Big Sur 11.0.1 让2K屏幕开启Hidpi

    首先来个成果图: 一.复制显示器配置文件 终端输入命令:cd /System/Library/Displays/Contents/Resources/Overrides 接着输入:open . 打开D ...

  8. GaussDB(DWS)磁盘维护:vacuum full执行慢怎么办?

    摘要:在数据库中用于维护数据库磁盘空间的工具是VACUUM,其重要的作用是删除那些已经标示为删除的数据并释放空间. vacuum的功能 回收空间 数据库总是不断地在执行删除,更新等操作.良好的空间管理 ...

  9. AWT09-弹球小游戏

    1.补充 为了让Java绘制动画,可以借助Swing的定时器,其构造为: 方法名 说明 Timer(int delay,ActionListener listener) 每间隔delay毫秒,自动触发 ...

  10. JavaScript判断视频编码是否为h.264

    1.视频编码是什么? 现在视频编码主流是h.264,对应着输入格式为AVC H.264/AVC是2003年制定的视频编码压缩标准 ,集中了以往标准的优点,并吸收了以往标准制定中积累的经验,采用简洁设计 ...