java并发编程代码示例_java并发编程之同步器代码示例

java并发编程之同步器代码示例

发布时间:2020-09-08 16:53:41

来源:脚本之家

阅读:58

作者:Blessing_H

同步器是一些使线程能够等待另一个线程的对象,允许它们协调动作。最常用的同步器是CountDownLatch和Semaphore,不常用的是Barrier和Exchanger

队列同步器AbstractQueuedSynchronizer是用来构建锁或者其他同步组件的基础框架,它内部使用了一个volatiole修饰的int类型的成员变量state来表示同步状态,通过内置的FIFO队列来完成资源获取线程的排队工作。

同步器的主要使用方式是继承,子类通过继承同步器并实现它的抽象方法来管理同步状态,在抽象方法的实现过程中免不了要对同步状态进行修改,这时就需要使用同步器来提供的3个方法(getState()、setState(intnewState)/和compareAndSetState(intexpect,intupdate))来进行操作,因为他们能够保证状态的改变是安全的。子类推荐被定义为自定义同步组件的静态内部类,同步器自身没有实现任何同步接口,它仅仅是定义了若干同步状态获取个释放的方法来供自定义同步组件使用,同步器既可以独占式的获取同步状态,也可以支持共享式的获取同步状态,这样就可以方便实现不同类型的同步组件(ReentrantLock、ReadWriteLock、和CountDownLatch等)。

同步器是实现锁的关键,在锁的实现中聚合同步器,利用同步器实现锁的语义。他们二者直接的关系就是:锁是面向使用者的,它定义了使用者与锁交互的接口,隐藏了实现的细节;同步器则是面向锁的实现者,它简化了锁的实现方式,屏蔽了同步状态管理、线程的排队、等待与唤醒等底层操作。锁和同步器很好的隔离了使用者与实现者所需关注的领域。

同步器的设计是基于模版方法模式实现的,使用者需要继承同步器并重写这顶的方法,随后将同步器组合在自定义同步组件的实现中,并调用同步器提供的模版方法,而这些模版方法将会调用使用者重写的方法。

同步器提供的模版方法基本上分为3类:独占式获取锁与释放同步状态、共享式获取与释放同步状态和查询同步队列中的等待线程情况。自定义同步组件将使用同步器提供的模版方法来实现自己的同步语义。倒计数器锁存器是一次性障碍,允许一个或者多个线程等待一个或者多个其它线程来做某些事情。CountDownLatch的唯一构造器带一个int类型的参数,这个int参数是指允许所有在等待线程被处理之前,必须在锁存器上调用countDown方法的次数。

EG:

package hb.java.thread;

import java.util.concurrent.CountDownLatch;

/**

*

* @author hb

* CountDownLatch最重要的方法是countDown()和await(),前者主要是倒数一次,后者是等待倒数到0,如果没有到达0

* ,就只有阻塞等待了。 *JAVA同步器之

* CountDownLatch(不能循环使用,如果需要循环使用可以考虑使用CyclicBarrier) 两种比较常规用法: 1:new

* CountDownLatch(1);所有的线程在开始工作前需要做一些准备工作,当所有的线程都准备到位后再统一执行时有用 2:new

* CountDownLatch(THREAD_COUNT);当所有的线程都执行完毕后,等待这些线程的其他线程才开始继续执行时有用

*/

public class CountDownLatchTest {

private static final int THREAD_COUNT = 10;

// 在调用startSingal.countDown()之前调用了startSingal.await()的线程一律等待,直到startSingal.countDown()的调用

private static final CountDownLatch startSingal = new CountDownLatch(1);

// 在finishedSingal的初始化记数量通过调用finishedSingal.countDown()减少为0时调用了finishedSingal.await()的线程一直阻塞

private static final CountDownLatch finishedSingal = new CountDownLatch(

THREAD_COUNT);

public static void main(String[] args) throws InterruptedException {

for (int i = 0; i < THREAD_COUNT; i++) {

new Thread("Task " + i) {

public void run() {

System.out.println(Thread.currentThread().getName()

+ " prepared!!");

try {

startSingal.await();

}

catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println(Thread.currentThread().getName()

+ " finished!!");

finishedSingal.countDown();

}

;

}

.start();

}

Thread.sleep(1000);

startSingal.countDown();

// 所有的线程被唤醒,同时开始工作.countDown 方法的线程等到计数到达零时才继续

finishedSingal.await();

// 等待所有的线程完成!!

System.out.println("All task are finished!!");

}

}

package hb.java.thread;

import java.util.concurrent.BrokenBarrierException;

import java.util.concurrent.CyclicBarrier;

/**

*

* JAVA同步器之Barrier(能够循环使用,当计数器增加到Barrier的初始化计数器之后马上会被置为0为下一次循环使用做准备)

* Barrier能够为指定的一个或多个(一般为多个)线程设置一道屏障,只有当所有的线程都到达该屏障后才能一起冲过该屏障继续其他任务 一般可以new

* CyclicBarrier(ThreadCount)来进行初始化,也可以new

* CyclicBarrier(ThreadCount,RunableAction)当初始化数量的线程都调用

* 了await()方法后触发RunableAction线程,也可以通过初始化一个new

* CyclicBarrier(ThreadCount+1)的Barrier在前置线程未执行完成时一直阻塞一个或多个

* 后续线程,这一点类似于CountDownLatch

*/

public class BarrierTest {

private static final int THREAD_COUNT = 10;

private static final CyclicBarrier barrier = new CyclicBarrier(

THREAD_COUNT + 1, new Runnable() {

@Override

public void run() {

System.out.println("All task are prepared or finished!!");

}

}

);

public static void main(String[] args) throws InterruptedException,

BrokenBarrierException {

for (int i = 0; i < THREAD_COUNT; i++) {

new Thread("Task " + i) {

public void run() {

try {

System.out.println(Thread.currentThread().getName()

+ " prepared!!");

barrier.await();

}

catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

catch (BrokenBarrierException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

// do something

System.out.println(Thread.currentThread().getName()

+ " finished!!");

}

;

}

.start();

}

barrier.await();

// --------------开始准备循环使用--------------

for (int i = 0; i < THREAD_COUNT; i++) {

new Thread("Task " + i) {

public void run() {

// do something

System.out.println(Thread.currentThread().getName()

+ " finished!!");

try {

barrier.await();

}

catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

catch (BrokenBarrierException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

;

}

.start();

}

barrier.await();

}

}

package hb.java.thread;

import java.util.ArrayList;

import java.util.List;

import java.util.concurrent.Exchanger;

public class ExchangerTest {

final static Exchanger> exchanger = new Exchanger>();

public static void main(String[] args) {

new Producer("Producer", exchanger).start();

new Consumer("Consumer", exchanger).start();

}

static class Producer extends Thread {

private Exchanger> exchanger;

/**

*

*/

public Producer(String threadName, Exchanger> exchanger) {

super(threadName);

this.exchanger = exchanger;

}

/*

* (non-Javadoc)

*

* @see java.lang.Thread#run()

*/

@Override

public void run() {

List products = new ArrayList();

for (int i = 0; i < 10; i++) {

products.add("product " + i);

}

try {

List results = exchanger.exchange(products);

System.out.println("get results from consumer");

for (String s : results) {

System.out.println(s);

}

}

catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

static class Consumer extends Thread {

private Exchanger> exchanger;

/**

*

*/

public Consumer(String threadName, Exchanger> exchanger) {

super(threadName);

this.exchanger = exchanger;

}

/*

* (non-Javadoc)

*

* @see java.lang.Thread#run()

*/

@Override

public void run() {

List products = new ArrayList();

for (int i = 0; i < 10; i++) {

products.add("consumed " + i);

}

try {

List results = exchanger.exchange(products);

System.out.println("got products from produces");

for (String s : results) {

System.out.println(s);

}

}

catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

}

总结

以上就是本文关于java并发编程之同步器代码示例的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站:

深入分析java并发编程中volatile的实现原理

Javaweb应用使用限流处理大量的并发请求详解

java并发学习之BlockingQueue实现生产者消费者详解

如有不足之处,欢迎留言指出。

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

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

相关文章

(需求实战_02)_ftp连接下载指定.zip类型文件

文章目录一、需求文档说明二、脚本解释/说明三、脚本内容一、需求文档说明 序号要求说明①协议使用ftp协议远程下载②文件类型.zip③文件名acd_UPIDDGWL④远程下载目录APEP/⑤本服务器下载存放目录/ablacklist/xmldata/Lists/PEP 二、脚本解释/说明 脚本拆解释义说明执行命令…

50多种适合机器学习和预测应用的API,你的选择是?(2018年版本)

摘要&#xff1a; 本文盘点了2018年以来人脸和图像识别、文本分析、自然语言处理、情感分析、语言翻译、 机器学习和预测这几个领域常用的API&#xff0c;读者可以根据自己需求选择合适的API完成相应的任务。对于做工程项目和搞科研的人来说&#xff0c;有现成的模块或工具使用…

谷歌10月15日发布 Pixel 4;高通以31亿美元收购与TDK公司权益;甲骨文、VMware就云技术及支持达成协议……...

关注并标星星CSDN云计算极客头条&#xff1a;速递、最新、绝对有料。这里有企业新动、这里有业界要闻&#xff0c;打起十二分精神&#xff0c;紧跟fashion你可以的&#xff01;每周三次&#xff0c;打卡即read更快、更全了解泛云圈精彩newsgo go go 荣耀 Play 3&#xff08;图片…

天线巴伦制作和原理_10米段的春天 | 用自制环型天线+改装SDR接收器27MHz采访实录...

&#xff28;&#xff26;部分包括&#xff19;个不同的波段&#xff0c;范围从&#xff11;&#xff0e;&#xff18;&#xff2d;&#xff28;&#xff5a;到&#xff12;&#xff19;&#xff0e;&#xff17;&#xff2d;&#xff28;&#xff5a;&#xff0c;它们通常也称…

学习笔记CB012: LSTM 简单实现、完整实现、torch、小说训练word2vec lstm机器人

摘要&#xff1a; 真正掌握一种算法&#xff0c;最实际的方法&#xff0c;完全手写出来。 LSTM&#xff08;Long Short Tem Memory&#xff09;特殊递归神经网络&#xff0c;神经元保存历史记忆&#xff0c;解决自然语言处理统计方法只能考虑最近n个词语而忽略更久前词语的问题…

(需求实战_03)_shell脚本 sftp协议下载文件

文章目录一、需求文档说明二、脚本解释/说明三、脚本内容3.1. 案例脚本3.2. 案例脚本升级一、需求文档说明 序号要求说明①协议使用sftp协议远程下载②文件类型.zip③文件名UPDATA④远程下载目录PEDP/⑤本服务器下载存放目录/app/xmldata/Lists 二、脚本解释/说明 脚本拆解释…

JAVA实现onvif的ptz控制_使用Onvif协议进行设备PTZ云台控制

接上一篇使用Onvif协议最重要的应用就是对设备进行PTZ云台控制&#xff0c;PTZ控制包含转动、变焦等&#xff0c;这里我们主要讨论常用的转动和变焦(也就是放大缩小)流程要进行设备PTZ控制&#xff0c;我们首先需要获取到设备的Device Service Address和此设备的用户名密码前两…

DataWorks支持PyODPS类型任务

摘要&#xff1a; 昨天&#xff0c;DataWorks推出了PYODPS任务类型&#xff0c;集成了Maxcompute的Python SDK&#xff0c;可在DataWorks的PYODPS节点上直接编辑Python代码操作Maxcompute&#xff0c;也可以设置调度任务来处理数据&#xff0c;提高数据开发效率。昨天&#xff…

vue base64图片不显示_技巧 | word中插入的图片显示不完整怎么办?

已经好久没有更新了&#xff0c;都快忘记有这个公众号存在了~这几个月发生了很多事情&#xff0c;工作上的任务也迟迟没有减轻&#xff0c;之前保持的日记也已经很久没有写了。但是觉得要是没有什么用什么方式将脑袋中时不时飘过的念头记录下来的话&#xff0c;过段时间就会完全…

重磅 | 华为发布绝杀计算战略!投15亿美元打造开放生态,全球最快AI训练集群Atlas 900,绝了!...

戳蓝字“CSDN云计算”关注我们哦&#xff01; 文 | 阿晶、丹丹、王银发于上海华为HC大会现场出品 | CSDN云计算&#xff08;ID&#xff1a;CSDNcloud&#xff09; 科技的不断发展正逐步加速智能世界的到来。一直&#xff0c;华为致力于提供经济且充裕的算力&#xff0c;力图像使…

python制作圆形按钮_C#圆形按钮,非常漂亮动态

【实例简介】C#圆形按钮&#xff0c;非常漂亮动态 Button,有源代码和例子&#xff0c;这是网上很少有的&#xff0c;兄弟们快下载呀&#xff01;【实例截图】【核心代码】PulseButton└── PulseButton├── Backup│ ├── PulseButton│ │ ├── ClassDiagram1.cd…

(需求实战_04)_定时压缩昨天指定文件并删除

文章目录一、需求文档说明二、脚本设置三、脚本内容一、需求文档说明 序号要求说明①协议使用sftp协议远程下载②文件类型.zip③文件名acd_UPIDDGWL④远程下载目录PEDP/⑤本服务器下载存放目录/ablacklist/xmldata/Lists 二、脚本设置 命令释义说明crontab -e编辑crontab8 0 …

90后实习生,是如何成长为阿里云分布式NoSQL领域专家

摘要&#xff1a; 我是亦征&#xff0c;本名王怀远&#xff0c;现在是阿里云存储服务团队的研发&#xff0c;正值五四青年节&#xff0c;受云栖社区邀请&#xff0c;来分享下自己的成长故事。从5年前第一次进入阿里云实习到如今&#xff0c;我一直都在表格存储TableStore团队&a…

AI新时代-大神教你使用python+Opencv完成人脸解锁(附源码)

摘要&#xff1a; 好吧&#xff0c;伙计们&#xff0c;我回来了。说我拖更不写文章的可以过来用你的小拳拳狠命地捶我胸口.... 那么今天我们来讲关于使用pythonopencvface来实现人脸验证及人脸解锁。代码量同样不多&#xff0c;你可以将这些代码运用在其它一些智能领域&#xf…

java foreach并行_使用foreach在Java中迭代并行数组的漂亮方法

Sean Adkinso..9这是一个有趣的练习.我创建了一个名为ParallelList的对象,它接受可变数量的类型化列表,并且可以遍历每个索引处的值(作为值列表返回):public class ParallelList implements Iterable> {private final List> lists;public ParallelList(List... lists) {t…

zTree笔记,设置无法勾选父节点(禁用父节点)和父节点禁用时回显选中子节点时关联父节点状态

名称链接zTree APIhttp://www.treejs.cn/v3/api.phpzTree Demohttp://www.treejs.cn/v3/demo.php#_101 最近又用到了zTree&#xff0c;虽然zTree的APi已经很全很方便很易懂了&#xff0c;但是难免有的方法找不到。为了方便他人方便自己&#xff0c;做下笔记记录下 zTree笔记1 …

你需要知道的那些 redis 数据结构(前篇)

戳蓝字“CSDN云计算”关注我们哦&#xff01; 作者 | 饿了么物流技术团队来源 | CSDN 企业博客redis 对于团队中的同学们来说是非常熟悉的存在了&#xff0c;我们常用它来做缓存、或是实现分布式锁等等。对于其 api 中提供的几种数据结构&#xff0c;大家也使用得得心应手。api…

Tensorflow快餐教程(6) - 矩阵分解

摘要&#xff1a; 特征分解&#xff0c;奇异值分解&#xff0c;Moore-Penrose广义逆矩阵分解特征向量和特征值我们在《线性代数》课学过方阵的特征向量和特征值。定义&#xff1a;设A∈FnnA∈Fnn是n阶方阵。如果存在非零向量X∈Fn1X∈Fn1使AXλXAXλX对某个常数λ∈Fλ∈F成立&…

ZTree的全选 反选 全不选 取消 清空

全选 //全选$(#c_all).on(click,function (e) {var zTree $.fn.zTree.getZTreeObj("treeMenu");//得到tree对象 treeMenu是我的treeidvar node zTree.getNodes();//得到全部节点var nodes zTree.transformToArray(node);//全部节点转换成数组arrayvar checkNode …

对数周期天线hfss建模_HFSS也有金手指,FADDM招式详解

FADDM(Finite Array Domain Decomposition Method)即有限大阵区域分解法是HFSS针对周期阵列天线的一种高效仿真方法,这种方法不仅能提升天线阵列建模和求解的效率&#xff0c;还能保证仿真结果的精准度。FADDM的优势同样的硬件可求解更大规模的阵列与在HFSS全模型求解具有同样精…