java线程——信号量(Semaphore)+障栅(CyclicBarrier)

【0】README

0.1)以下内容转自网络,旨在理清 “java线程——信号量(Semaphore)+障栅(CyclicBarrier)”的相关知识


【1】信号量

1.1)信号量定义:从概念上讲,一个信号量管理许多的许可证。为了通过信号量,线程通过调用 acquire 请求许可;
1.2)其实没有实际的许可对象, 信号量仅仅是维护了一个计数;
1.3)看个荔枝:转自 http://www.cnblogs.com/whgw/archive/2011/09/29/2195555.html

  • 1.3.1) Semaphore当前在多线程环境下被扩放使用,操作系统的信号量是个很重要的概念,在进程控制方面都有应用。Java 并发库 的Semaphore 可以很轻松完成信号量控制,Semaphore可以控制某个资源可被同时访问的个数,通过 acquire() 获取一个许可,如果没有就等待,而 release() 释放一个许可。比如在Windows下可以设置共享文件的最大客户端访问个数。
  • 1.3.2)荔枝说明: Semaphore实现的功能就类似厕所有5个坑,假如有10个人要上厕所,那么同时只能有多少个人去上厕所呢? 同时只能有5个人能够占用,当5个人中 的任何一个人让开后,其中等待的另外5个人中又有一个人可以占用了。另外等待的5个人中可以是随机获得优先机会,也可以是按照先来后到的顺序获得机会,这取决于构造Semaphore对象时传入的参数选项。单个信号量的Semaphore对象可以实现互斥锁的功能,并且可以是由一个线程获得了“锁”,再由另一个线程释放“锁”,这可应用于死锁恢复的一些场合。
  • 1.3.3)Semaphore维护了当前访问的个数,提供同步机制,控制同时访问的个数。 在数据结构中链表可以保存“无限”的节点,用Semaphore可以实现有限大小的链表。另外重入锁 ReentrantLock 也可以实现该功能,但实现上要复杂些。

1.4)下面的Demo中申明了一个只有5个许可的Semaphore,而有10个线程要访问这个资源,通过acquire()和release()获取和释放访问许可。

  • for full source code, please visit : https://github.com/pacosonTang/core-java-volume/blob/master/chapter14/SemaphoreTest.java
    这里写图片描述

  • source code at a glance :

package com.corejava.chapter14_6;import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import static java.lang.System.*;public class SemaphoreTest
{public static void main(String[] args){// thread poolExecutorService exec = Executors.newCachedThreadPool();// there must be 5 threads accessing certain sourcefinal Semaphore semaphore = new Semaphore(5);for (int i = 0; i < 10; i++){final int num = i;Runnable run = new Runnable() // create 10 threads circularly{@Overridepublic void run(){try{semaphore.acquire();// acquire permissionout.println("accessing " + num);Thread.sleep((long)(Math.random()*10000));semaphore.release(); // release permissionout.println("semaphore.availablePermits = " + semaphore.availablePermits());}catch(InterruptedException e){e.printStackTrace();}}};exec.execute(run);// thread's startup}exec.shutdown(); // shutdown all of threads}
}

【2】障栅

2.1)定义: CyclicBarrier 类实现了一个集结点 称为障栅;

  • 2.1.1)障栅的作用:考虑大量线程运行在一次计算的不同部分的情形: 当所有部分都准备好时, 需要吧结果组合到一起, 当一个线程完成了它的那部分任务后, 我们让它运行到障栅处。 一旦所有的线程都到达了这个 障栅, 障栅就撤销了, 线程就可以继续运行了了;

  • step1)构造一个障栅,并给出参与的线程数:

CyclicBarrier cyclicBarrier = new CyclicBarrier(2, new Runnable()
  • step2) 每个线程做一些工作, 完成后再障栅上调用 await()方法
public void run(){arr[id] = new Random().nextInt(100);try{out.println(id + " starts to have a rest!");cyclicBarrier.await();out.println(id + "wake up!");} catch (Exception e){e.printStackTrace();}
  • step3) 如果任何一个在 障栅上等待的线程离开了障栅, 那么障栅就被破坏了;
  • step4)可以提供一个可选的 障栅 动作(Barrier Action), 当所有线程到达障栅的时候就会执行这个工作:
Runnable barrierAction = ...
CyclicBarrier cyclicBarrier = new CyclicBarrier(nthreds, barrienAction)
CyclicBarrier cyclicBarrier = new CyclicBarrier(2, new Runnable()
  • step5) 障栅被称为是循环的, 因为可以在所有等待线程被释放后被重用。 在这一点上, 有别于 CountDownLatch, CountDownLatch 只能被使用一次;

2.2)看个荔枝: 转自 http://my.oschina.net/summerpxy/blog/189799

  • 2.2.1)CyclicBarrier称为障栅,这个类有什么作用呢? 这个类是用来同步线程用的。以小黑车为例(就是盘踞在地铁口的黑出租),一般小黑车是坐4个人,只有4个人都满了之后小黑车才会走,那么如果你是第一个来的,进车坐下,等第二个人来。第二个人来了,等第三个人,如此直到所有的4个人满了之后小黑车才开车。那么这个类也是一样的。

    • 第一个线程:运行到障栅出,等待第二个线程到达。
    • 第二个线程:运行到障栅出,等待第三个线程到达。
    • 第三个线程:运行到障栅出,等待第四个线程到达。
    • 第四个线程:运行到障栅出,障栅解除,所有线程都开始执行。
  • 2.2.2)荔枝代码:下面是一个demo,arr[0]和arr[1]的赋值是两个线程完成的,当两个线程的赋值结束之后才会得到arr[2]的值:
    • for full source code , please visit https://github.com/pacosonTang/core-java-volume/blob/master/chapter14/CyclicBarrierTest.java

这里写图片描述

  • source code at a glance :
package com.corejava.chapter14_6;import java.util.Random;
import java.util.concurrent.CyclicBarrier;
import static java.lang.System.*;public class CyclicBarrierTest
{public static void main(String[] args){int[] arr = new int[3];//可以提供一个可选的 障栅 动作(Barrier Action), 当所有线程到达障栅的时候就会执行这个工作//CyclicBarrier cyclicBarrier = new CyclicBarrier(nthreds, barrienAction)CyclicBarrier cyclicBarrier = new CyclicBarrier(2, new Runnable(){@Overridepublic void run(){arr[2] = arr[0] + arr[1];for (int i = 0; i < arr.length; i++)out.println("arr[" + i +"] = " + arr[i]);}});new Thread(new MyCyclicBarrier(1, arr, cyclicBarrier)).start();new Thread(new MyCyclicBarrier(0, arr, cyclicBarrier)).start();}
}class MyCyclicBarrier implements Runnable
{int id;int[] arr;CyclicBarrier cyclicBarrier;public MyCyclicBarrier(int id, int[] arr, CyclicBarrier barrier){this.id = id;this.arr = arr;this.cyclicBarrier = barrier;}@Overridepublic void run(){arr[id] = new Random().nextInt(100);try{out.println(id + " starts to have a rest!");cyclicBarrier.await();out.println(id + " wake up!");} catch (Exception e){e.printStackTrace();}}}

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

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

相关文章

C#的foreach

一、foreach语句 C#的foreach 语句不会解析为IL 代码中的foreach 语句。 C#编译器会把foreach 语句转换为 IEnumerable 接口的方法和属性。 下面是一个简单的foreach 语句&#xff0c;它迭代数组中的所有元素&#xff0c;并逐个显示它们&#xff1a; foreach (A a in aas)…

linux中echo命令不输出换行,shell脚本echo输出不换行功能增强实例

这是第8/101个脚本There are as many ways to solve this quirky echo problem as there are pages in this book. One of my favorites is very succinct:function echon{echo "$*" | awk { printf "%s" $0 }}You may prefer to avoid the overhead incur…

java联接pg库_成为Java流大师–第5部分:将联接的数据库表转换为流

java联接pg库是否可以将联接的数据库表转换为Java Stream&#xff1f; 答案是肯定的。 由于我们已经多次提出这个问题&#xff0c;因此我们决定写另一篇动手实验文章&#xff0c;说明如何执行更高级的Stream Joins。 因此&#xff0c;这里是第六篇中的第五篇&#xff0c;后面还…

java线程——什么是线程?

【0】README 0.1&#xff09; 本文描述转自 core java volume 1&#xff0c; 源代码为原创&#xff0c;旨在理解 java线程——什么是线程&#xff1f; 的相关知识&#xff1b; 0.2&#xff09;线程定义&#xff1a;一个程序可以执行多个任务&#xff0c;每一个任务成为线程&a…

C#的类修饰符和成员修饰符

一、类修饰符 类修饰符&#xff1a;public、internal、 partial、abstract、sealed、static、new、protected、private、protected internal1、public&#xff1a;访问不受限制的&#xff0c;所有的本程序集以及其他的程序集里面的类都能够访问2、internal&#xff1a;本程序集…

linux 端口方法防火墙,Linux 打开端口方法(防火墙操作)

Linux防火墙操作(经测试部分命令无效)关闭防火墙:service iptables stop开启防火墙:service iptables start防火墙状态:service iptables status永久关闭:chkconfig iptables off永久开启:chkconfig iptables on方法一(命令):1. 开放端口命令&#xff1a; /sbin/iptables -I IN…

kafka 发布-订阅模式_使用Apache Kafka作为消息系统的发布-订阅通信中的微服务,并通过集成测试进行了验证...

kafka 发布-订阅模式发布-订阅消息系统在任何企业体系结构中都起着重要作用&#xff0c;因为它可以实现可靠的集成而无需紧密耦合应用程序。 在解耦的系统之间共享数据的能力并不是一个容易解决的问题。 考虑一个企业&#xff0c;其中具有使用不同语言和平台独立构建的多个应用…

java线程——中断线程+线程状态+线程属性(优先级)

【0】README 0.1&#xff09; 本文描述转自 core java volume 1&#xff0c; 源代码为原创&#xff0c;旨在理解 java线程——中断线程线程状态线程属性&#xff08;优先级&#xff09; 的相关知识&#xff1b; 【1】中断线程 1.1&#xff09;当线程的run方法执行方法体中最…

C#的protected internal

关于C#的 protected internal&#xff0c;也许你在网上可以找到两种解释&#xff1a;第一种解释是&#xff0c;protected or internal &#xff0c;即在本程序集或其他程序集继承的子类可以访问。 第二种解释是&#xff0c;protected and internal&#xff0c;即在本类或本程序…

pae扩展内存 linux,浅析linux内核内存管理之PAE

浅析linux内核内存管理之PAE早期Intel处理器从80386到Pentium使用32位物理地址&#xff0c;理论上&#xff0c;这样可以访问4GB的RAM。然而&#xff0c;大型服务器需要大于4GB的RAM来同时运行数以千计的进程&#xff0c;近几年来这对Intel造成了压力&#xff0c;所以必须扩展32…

java线程同步——竞争条件的荔枝+锁对象

【0】README 0.1&#xff09; 本文描述转自 core java volume 1&#xff0c; 源代码为原创&#xff0c;旨在理解 java线程同步——竞争条件的荔枝锁对象 的相关知识&#xff1b; 0.2&#xff09; for full source code, please visit https://github.com/pacosonTang/core-ja…

Hibernate框架

一、Hibernate概述 1、Hibernate是一个基于元数据的轻量级的ORM框架。 (1)元数据&#xff08;Meta Data&#xff09;:data about data(数据的数据)&#xff0c;也就是说描述一个对象数据&#xff0c;相当于这个对象的上下文环境。 (2)轻量级&#xff1a;占用资源少&am…

java 线性回归算法_线性搜索或顺序搜索算法在Java中如何工作? 示例教程

java 线性回归算法大家好&#xff0c;之前&#xff0c;我讨论了二进制搜索算法的工作原理&#xff0c;并分享了在Java中实现二进制搜索的代码。 在那篇文章中&#xff0c;有人问我是否还有其他搜索算法&#xff1f; 如果数组中的元素未排序&#xff0c;又该如何使用它而不能使用…

linux安装i219网卡驱动下载,华硕E500 G5 (-INTEL I210 / I219-LM)网卡驱动12.17.10.7版下载,适用于Win10-64-驱动精灵...

驱动说明&#xff1a;-Windows-Intel(R) I210 Gigabit Network Connection with I/O Acceleration Technology (Intel(R) I/OAT) Software Version 23.2.0.1006 WHQL driver V12.14.7.0 for Windows Server 2012 R2 64 bit. Software Version 23.2.0.1006 WHQL driver V12.15.1…

java线程同步——条件对象+synchronized 关键字

【0】README 0.1&#xff09; 本文描述转自 core java volume 1&#xff0c; 源代码为原创&#xff0c;旨在理解 java线程同步——条件对象synchronized 关键字 的相关知识&#xff1b; 0.2&#xff09;for full source code &#xff1a; https://github.com/pacosonTang/co…

Hibernate之必须导入jar包

Hibernate必须导入的包 hibernate是ORM的解决方案&#xff0c;其底层对数据库的操作依赖于JDBC&#xff0c;所以必须先取得JDBC驱动程序&#xff0c;在这使用的是MySQL&#xff0c;所以必须至先取得MySQL的JDBC驱动程序 https://dev.mysql.com/downloads/connector/j/ Hibern…

赞扬别人团建评论_赞扬精心设计:基于属性的测试如何帮助我成为更好的开发人员...

赞扬别人团建评论开发人员的测试工具箱就是其中之一&#xff0c;很少保持不变。 可以肯定的是&#xff0c;一些测试实践已被证明比其他测试更有价值&#xff0c;但是&#xff0c;我们仍在不断寻找更好&#xff0c;更快和更具表现力的方法来测试我们的代码。 基于属性的测试 是 …

linux c read函数返回值,Linuxc - GNU Readline 库及编程简介

GNU Readline 库及编程简介简介用过 Bash 命令行的一定知道&#xff0c;Bash 有几个特性&#xff1a;TAB 键可以用来命令补全↑ 或 ↓ 键可以用来快速输入历史命令还有一些交互式行编辑快捷键&#xff1a;C-A / C-E 将光标移到行首/行尾C-B / C-F 将光标向左/向右移动一个位置C…

java泛型——桥方法

【0】README 0.1&#xff09;以下内容转自&#xff1a; http://www.cnblogs.com/ggjucheng/p/3352519.html 【1】泛型约束和局限性—— 类型擦除所带来的麻烦 1.1&#xff09;继承泛型类型的多态麻烦。&#xff08;—— 子类没有覆盖住父类的方法 &#xff09; 看看下面这个…

Hibernate框架之入门配置

一、Hibernate导入相关的包参考&#xff1a;http://blog.csdn.net/tunni/article/details/54982160这些包包括相应数据库驱动、hibernate.zip下lib目录下的jar包&#xff0c;其中必须包是required目录下的.jar二、在项目classpath&#xff08;类路径&#xff0c;即src目录下&am…