java count 在哪一类里_java 5线程中 Semaphore信号灯,CyclicBarrier类,CountDownLatch计数器以及Exchanger类使用...

先来讲解一下Semaphore信号灯的作用:

可以维护当前访问自身的线程个数,并提供了同步机制,

使用semaphore可以控制同时访问资源的线程个数

例如,实现一个文件允许的并发访问数。

请看下面的演示代码:

1 public classSemaphoreTest2 {3 public static voidmain(String[] args)4 {5 //创建一个带有缓存的线程池

6 ExecutorService service =Executors.newCachedThreadPool();7 //创建三个信号灯

8 final Semaphore sp = new Semaphore(3);//最多并发三个线程 此处可以按照需求去修改9 //开启十个线程

10 for (int i = 1; i <= 10; i++)11 {12 //只有三个线程可以同时进入 其余线程等待

13 service.execute(newRunnable()14 {15 @Override16 public voidrun()17 {18 try

19 {20 sp.acquire();//获取一盏信号灯

21 } catch(InterruptedException e)22 {23 e.printStackTrace();24 }25 System.out.println("线程 "+Thread.currentThread().getName()+" 进入"

26 + " ,当前已有 "+(3-sp.availablePermits())+ " 个并发");27 try

28 {29 Thread.sleep(new Random().nextInt(1000));30 } catch(InterruptedException e)31 {32 e.printStackTrace();33 }34 System.out.println("线程 "+Thread.currentThread().getName()+" 即将离开 ");35 sp.release();//释放

36 System.out.println("线程 "+Thread.currentThread().getName()+" 已经离开"

37 + " ,当前已有 "+(3-sp.availablePermits())+ " 个并发");38 }39 });40 }41 service.shutdown();42 }43 }

执行结果如下:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

线程 pool-1-thread-2 进入 ,当前已有 2个并发

线程 pool-1-thread-3 进入 ,当前已有 3个并发

线程 pool-1-thread-1 进入 ,当前已有 3个并发

线程 pool-1-thread-3即将离开

线程 pool-1-thread-3 已经离开 ,当前已有 2个并发

线程 pool-1-thread-4 进入 ,当前已有 3个并发

线程 pool-1-thread-1即将离开

线程 pool-1-thread-5 进入 ,当前已有 3个并发

线程 pool-1-thread-1 已经离开 ,当前已有 3个并发

线程 pool-1-thread-2即将离开

线程 pool-1-thread-2 已经离开 ,当前已有 2个并发

线程 pool-1-thread-6 进入 ,当前已有 3个并发

线程 pool-1-thread-6即将离开

线程 pool-1-thread-6 已经离开 ,当前已有 2个并发

线程 pool-1-thread-7 进入 ,当前已有 3个并发

线程 pool-1-thread-7即将离开

线程 pool-1-thread-7 已经离开 ,当前已有 2个并发

线程 pool-1-thread-8 进入 ,当前已有 3个并发

线程 pool-1-thread-4即将离开

线程 pool-1-thread-4 已经离开 ,当前已有 2个并发

线程 pool-1-thread-9 进入 ,当前已有 3个并发

线程 pool-1-thread-5即将离开

线程 pool-1-thread-5 已经离开 ,当前已有 2个并发

线程 pool-1-thread-10 进入 ,当前已有 3个并发

线程 pool-1-thread-10即将离开

线程 pool-1-thread-10 已经离开 ,当前已有 2个并发

线程 pool-1-thread-8即将离开

线程 pool-1-thread-8 已经离开 ,当前已有 1个并发

线程 pool-1-thread-9即将离开

线程 pool-1-thread-9 已经离开 ,当前已有 0 个并发

View Code

Semaphore信号灯可以控制并发数,保证每次最多只能有三个线程在线程池中。

CyclicBarrier类的使用,可以模拟现实生活中的多人等待上车的情形,例如多人去旅行,那么当A到达集合点时,不能立即出发,必须等到B也到达集合点,那么A和B必须等到C也到达集合点,此时,三人可以坐车出发去下一站。该类就可以实现此功能,请看如下代码。

1 public classCyclicBarrierTest2 {3 public static voidmain(String[] args)4 {5 //创建一个带有缓存的线程池

6 ExecutorService service =Executors.newCachedThreadPool();7 //指定三个线程 只有当三个线程同时到达时 程序才会往下执行

8 final CyclicBarrier cb = new CyclicBarrier(3);9

10 for (int i = 0; i < 3; i++)11 {12 Runnable runnable = newRunnable()13 {14 @Override15 public voidrun()16 {17 try

18 {19 /**

20 * cb.getNumberWaiting():从0开始,获取当前等待的线程数量21 */

22 //第一个

23 Thread.sleep(new Random().nextInt(1000));24 System.out.println("线程 "+Thread.currentThread().getName()+" 即将到达集合地点1,"

25 + "当前已有"+(cb.getNumberWaiting()+1)+" 个线程,"+(cb.getNumberWaiting()==2?"都到齐了,继续走啊":"正在继续等待"));26 cb.await();//让线程等待27

28 //第二个

29 Thread.sleep(new Random().nextInt(1000));30 System.out.println("线程 "+Thread.currentThread().getName()+" 即将到达集合地点2,"

31 + "当前已有"+(cb.getNumberWaiting()+1)+" 个线程,"+(cb.getNumberWaiting()==2?"都到齐了,继续走啊":"正在继续等待"));32 cb.await();33

34 //第三个

35 Thread.sleep(new Random().nextInt(1000));36 System.out.println("线程 "+Thread.currentThread().getName()+" 即将到达集合地点3,"

37 + "当前已有"+(cb.getNumberWaiting()+1)+" 个线程,"+(cb.getNumberWaiting()==2?"都到齐了,继续走啊":"正在继续等待"));38 cb.await();39 } catch (InterruptedException |BrokenBarrierException e)40 {41 e.printStackTrace();42 }43 }44 };45 service.execute(runnable);46 }47

48 service.shutdown();//关闭线程池

49 }50 }

如下是执行结果:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 线程 pool-1-thread-2即将到达集合地点1,当前已有1 个线程,正在继续等待2 线程 pool-1-thread-1即将到达集合地点1,当前已有2 个线程,正在继续等待3 线程 pool-1-thread-3即将到达集合地点1,当前已有3 个线程,都到齐了,继续走啊4 线程 pool-1-thread-2即将到达集合地点2,当前已有1 个线程,正在继续等待5 线程 pool-1-thread-1即将到达集合地点2,当前已有2 个线程,正在继续等待6 线程 pool-1-thread-3即将到达集合地点2,当前已有3 个线程,都到齐了,继续走啊7 线程 pool-1-thread-1即将到达集合地点3,当前已有1 个线程,正在继续等待8 线程 pool-1-thread-2即将到达集合地点3,当前已有2 个线程,正在继续等待9 线程 pool-1-thread-3 即将到达集合地点3,当前已有3 个线程,都到齐了,继续走啊

View Code

CountDownLatch计数器的使用:

* 演示一个计数器CountDownLatch

* 模拟百米赛跑

* 1个裁判 吹口哨

* 3个运动员

1 public classCountDownLatchTest2 {3 public static voidmain(String[] args)4 {5 //创建一个带有缓存的线程池

6 ExecutorService service =Executors.newCachedThreadPool();7 final CountDownLatch cdOrder = new CountDownLatch(1);//裁判

8 final CountDownLatch cdAnswer = new CountDownLatch(3);//运动员

9 for (int i = 0; i < 3; i++)10 {11 Runnable runnable = newRunnable()12 {13 @Override14 public voidrun()15 {16 try

17 {18 System.out.println("线程"+Thread.currentThread().getName()+" 正准备接收命令 ");19 cdOrder.await();//等待计数器归0时 代码向下走

20 System.out.println("线程"+Thread.currentThread().getName()+" 已接收命令 ");21 Thread.sleep(new Random().nextInt(1000));22 System.out.println("线程"+Thread.currentThread().getName()+" 回应命令处理结果 ");23 cdAnswer.countDown();//没调用一次该方法 就会将当前计数器上的计数减1

24 } catch(InterruptedException e)25 {26 e.printStackTrace();27 }28 }29 };30 service.execute(runnable);31 }32

33

34 //主线恒

35 try

36 {37 Thread.sleep(new Random().nextInt(1000));38 System.out.println("线程"+Thread.currentThread().getName()+" 即将发布命令 ");39 cdOrder.countDown();//相当于把计数器身上的计数减1

40 System.out.println("线程"+Thread.currentThread().getName()+" 已发送命令,正在等待结果 ");41 cdAnswer.await();42 System.out.println("线程"+Thread.currentThread().getName()+" 已收到所有相应结果");43 } catch(InterruptedException e)44 {45 e.printStackTrace();46 }47 service.shutdown();//关闭线程池

48 }49 }

如下是执行结果:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 线程pool-1-thread-1正准备接收命令2 线程pool-1-thread-2正准备接收命令3 线程pool-1-thread-3正准备接收命令4 线程main 即将发布命令5 线程main 已发送命令,正在等待结果6 线程pool-1-thread-1已接收命令7 线程pool-1-thread-2已接收命令8 线程pool-1-thread-3已接收命令9 线程pool-1-thread-2回应命令处理结果10 线程pool-1-thread-3回应命令处理结果11 线程pool-1-thread-1回应命令处理结果12 线程main 已收到所有相应结果

View Code

Exchanger类可以实现两个线程之间的数据交换:

1 public classExchangerTest2 {3 public static voidmain(String[] args)4 {5 //创建一个带有缓存的线程池

6 ExecutorService service =Executors.newCachedThreadPool();7 final Exchanger changer = new Exchanger();8 //开启第一个任务

9 service.execute(newRunnable()10 {11 @Override12 public voidrun()13 {14 try

15 {16 String dtail1 = "zhangsan";//准备要交换出去的数据

17 System.out.println("线程 "+Thread.currentThread().getName()+" 正要把"+dtail1+"换出去");18 Thread.sleep(new Random().nextInt(1000));19 String dtail2 = changer.exchange(dtail1);//换回来的数据

20 System.out.println("线程 "+Thread.currentThread().getName()+"换回的数据为"+dtail2);21 } catch(InterruptedException e)22 {23 e.printStackTrace();24 }25 }26 });27

28 //开启第二个任务

29 service.execute(newRunnable()30 {31 @Override32 public voidrun()33 {34 try

35 {36 String dtail1 = "lisi";//准备要交换出去的数据

37 System.out.println("线程 "+Thread.currentThread().getName()+" 正要把"+dtail1+"换出去");38 Thread.sleep(new Random().nextInt(1000));39 String dtail2 = changer.exchange(dtail1);//换回来的数据

40 System.out.println("线程 "+Thread.currentThread().getName()+"换回的数据为"+dtail2);41 } catch(InterruptedException e)42 {43 e.printStackTrace();44 }45 }46 });47 service.shutdown();48 }49 }

如下是执行结果:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 线程 pool-1-thread-1正要把zhangsan换出去2 线程 pool-1-thread-2正要把lisi换出去3 线程 pool-1-thread-1换回的数据为lisi4 线程 pool-1-thread-2换回的数据为zhangsan

View Code

以上都是java 5中的一些知识点,大家可以根据实际工作中的需要进行选择使用!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/337908.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C/C++入门易错点及常用小技巧

点击上方蓝字关注我&#xff0c;了解更多咨询C语言诞生至今已有30多个年头了&#xff0c;主要集中在需要运行效率比较高的行业&#xff0c;比如现在的游戏开发以及高效服务器等等。C学习难度比其它语言都要高&#xff0c;这是不可否认的&#xff0c;其学习难度主要在于它的复杂…

quasar_Quasar和Akka –比较

quasaractor模型是用于容错和高度可扩展系统的设计模式。 角色是独立的工作程序模块&#xff0c;它们仅通过消息传递与其他角色进行通信&#xff0c;可以与其他角色隔离而失败&#xff0c;但是可以监视其他角色的故障并在发生这种情况时采取一些恢复措施。 角色是简单&#xff…

什么是自定义函数?精简回答

点击上方蓝字关注我&#xff0c;了解更多咨询1、自定义函数是程序员根据所要完成的功能&#xff0c;自己写出的源代码实现该功能。2、自定义函数和库函数一样&#xff0c;具有函数名&#xff0c;返回值类型&#xff0c;和函数参数。示例1&#xff1a;写一个函数找出两整数的值。…

C++ 创建文件夹的几种方式汇总确定不来看看???

点击上方蓝字关注我&#xff0c;了解更多咨询1、使用 system() 调用 dos 命令。2、使用头文件 direct.h 中的 access 和 mkdir 函数。关于 direct.h 我觉得 维基百科 上介绍的不错3、调用 Windows API 函数。4、调用 MFC 封装好的接口函数。不推荐此方法&#xff0c;出错的话会…

java socket 传送进度_java-★-Socket文件上传/进度条

客户端代码&#xff1a;1、客户端运行程序&#xff1a;package wtb.khd;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.io.DataOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.OutputStream;import …

c语言中typedef和define的区别

点击上方蓝字关注我&#xff0c;了解更多咨询1、typedef仅限于为类型定义符号名称。define不仅可以为类型定义别名&#xff0c;还可以为数值定义别名。例如&#xff0c;可以将1定义为ONE。2、typedef由编译器解释&#xff0c;define语句由预编译器处理。实例#include <stdio…

c语言中预处理器是什么?

点击上方蓝字关注我&#xff0c;了解更多咨询1、C语言有预处理器&#xff0c;Java中没有这个概念&#xff0c;其实只是文本替换工具。2、C的预处理器&#xff0c;即CPP&#xff0c;将在实际编译器中完成处理&#xff0c;所有预处理命令将从#开始。实例#include <stdio.h>…

垃圾回收算法以及垃圾回收器_什么是垃圾回收?

垃圾回收算法以及垃圾回收器以下是我们的垃圾收集手册中的一个示例&#xff0c;该手册将在接下来的几周内发布。 同时&#xff0c;花点时间熟悉垃圾收集的基础知识-这将是本书的第一章。 乍一看&#xff0c;垃圾收集应该处理顾名思义的问题–查找并丢弃垃圾。 实际上&#xff…

c语言中fgetc函数的介绍

点击上方蓝字关注我&#xff0c;了解更多咨询1、fgetc函数返回的字符实际上是文件流中位置指针指向的字符。当fgetc函数读取错误时&#xff0c;返回EOF并设置文件错误标志位。2、该函数以无符号char强制转换为int的形式返回读取的字符&#xff0c;如果到达文件末尾或出现读错&a…

花5分钟了解C语言基本语法元素快来

点击上方蓝字关注我&#xff0c;了解更多咨询C语言是一种编程语言&#xff0c;和其它语言一样&#xff0c;也定义了自己的语法和词汇。学习C语言&#xff0c;首先要学习C语言的词汇&#xff0c;再学习C语言的语法规则&#xff0c;然后由词汇构成语句&#xff0c;由语句构成源程…

c语言中ftell函数是什么

点击上方蓝字关注我&#xff0c;了解更多咨询1、C语言函数ftell用于获取文件位置指针当前位置相对于文件首的偏移字节数。2、通过ftell函数获取当前文件的大小&#xff0c;然后通过fread函数读取缓冲区。返回值&#xff0c;如果成功&#xff0c;该函数返回位置标识符的当前值&a…

jdk入门_JDK 9 REPL:入门

jdk入门会议是聚会Java名人的好地方。 Devoxx France是与Java语言架构师&#xff0c;前同事和老朋友Brian Goetz&#xff08; briangoetz &#xff09;见面的一个机会。 我们谈论了JDK 9&#xff0c;而他全都热衷于REPL。 他提到&#xff0c;尽管Java SE 9中有很多重要功能 &am…

c语言中局部变量是什么

点击上方蓝字关注我&#xff0c;了解更多咨询1、函数内部定义的变量称为局部变量&#xff0c;其作用域仅限于函数内部&#xff0c;离开函数后无效&#xff0c;使用后报错。2、局部变量只能在函数内部使用&#xff0c;离开函数后无效&#xff0c;再次使用会报错。实例#include &…

java接口自动化Excel占位符_基于maven+java+TestNG+httpclient+poi+jsonpath+ExtentReport的接口自动化测试框架...

接口自动化框架项目说明本框架是一套基于mavenjavaTestNGhttpclientpoijsonpathExtentReport而设计的数据驱动接口自动化测试框架&#xff0c;TestNG 作为执行器&#xff0c;poi用于读取存放于excel的接口用例&#xff0c;jsonPath用于校验返回值&#xff0c;以及提取返回值。本…

C语言为什么要定义short,int,long这么多整数类型?

点击上方蓝字关注我&#xff0c;了解更多咨询整数类型有int、short int、long int三种类型&#xff0c;用于需要不同存储空间的整数使用。整数类型有正整数和负整数之分&#xff0c;在C语言中&#xff0c;规定整型的最高位为符号位&#xff0c;最高位为“0”表示正数&#xff0…

c语言中函数参数类型的探究

点击上方蓝字关注我&#xff0c;了解更多咨询函数中的参数个数可以是0&#xff0c;也可以是一个或多个参数。下面我们带着这三种不同的情况&#xff0c;分别在c语言中进行讨论。1、函数没有参数&#xff0c;表示没有参数列表。int func1(); //声明一个函数&#xff0c;该函数…

c语言野指针产生的原因

点击上方蓝字关注我&#xff0c;了解更多咨询1、指针变量未初始化&#xff0c;任何指针变量刚被创建时不会自动成为 NULL 指针&#xff0c;它的缺省值是随机的。所以&#xff0c;指针变量在创建的同时应当被初始化&#xff0c;要么将指针设置为 NULL &#xff0c;要么让它指向合…

c语言中assert函数的使用注意

点击上方蓝字关注我&#xff0c;了解更多咨询1、使用assert检查函数开始时传入参数的合法性。2、每个assert只检验一个条件&#xff0c;因为在同时检验多个条件时&#xff0c;如果断言失败&#xff0c;就无法直观地判断哪个条件失败。实例int resetBufferSize(int nNewSize) {/…

es 调整gc_实际中进行GC调整

es 调整gc调优垃圾回收与任何其他性能调优活动没有什么不同。 您需要确保您了解当前的情况和所需的结果&#xff0c;而不是因为对应用程序的随机部分进行调整而产生了诱惑。 通常&#xff0c;只需执行以下过程即可&#xff1a; 陈述您的绩效目标 运行测试 测量 与目标比较…

c语言中assert函数是什么

点击上方蓝字关注我&#xff0c;了解更多咨询1、assert将通过检查表达式expresion的值来决定是否需要终止执行程序。2、如果表达式expresion的值是假的(即0)&#xff0c;它将首先向标准错误流stderr打印错误信息。通过调用abort函数终止程序运行。否则&#xff0c;assert没有效…