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实现生产者消费者详解

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

java并发编程代码示例_java并发编程之同步器代码示例相关推荐

  1. java 并发模型总类_java并发编程系列-内存模型基础

    java线程之间的通信对程序开发人员是完全透明的,内存的可见性问题很容易困扰很多开发人员.本篇博文将揭开java内存模型的神秘面纱,来看看内存模型到底是怎样的. 并发编程模型的分类 并发编程中需要处理 ...

  2. java实验指导答案华软_Java核心编程技术实验指导教程

    软件工程类 Java核心编程技术实验指导教程 作者:张屹, 蔡木生 所属类别:新世纪应用型高等教育软件专业系列规划教材 出版时间:2010年10月 ISBN:978-7-5611-5839-5前言 本 ...

  3. java的mysql语句规范_JAVA语言编程格式高级规范

    作为一位开发人员,都要有严格的代码规范.为此我总结了一些代码规范案例. 目 录 1. 前言 2. 试用范围 3. JAVA命名规范-- 3.1 公共约定 3.2 Java文件.包 3.3 类.接口命名 ...

  4. java面向对象编程的思想_java面向对象编程思想的理解

    1.我们总说java是一门面向对象编程的语言,那什么是面向对象呢? 我是这样理解的,对象是事物存在的实体,如,猪.狗,花早等都是对象,对象由两部分组成.面向对象编程的三大特点:继承,多态,类是封装对象 ...

  5. java子类代码块_java中父类子类静态代码块、构造代码块执行顺序

    父类静态(代码块,变量赋值二者按顺序执行) 子类静态 父类构造代码块 父类构造方法 子类构造代码块 子类构造方法 普通方法在实列调用的时候执行,肯定位于上面之后了 //父类A public class ...

  6. java 如何只暴露接口_Java并发异步编程,原来十个接口的活现在只需要一个接口就搞定...

    什么?对你没有听错,也没有看错 ..多线程并发执行任务,取结果归集~~ 不再忧愁-. 引言 先来看一些APP的获取数据,诸如此类,一个页面获取N多个,多达10个左右的一个用户行为数据,比如:点赞数,发 ...

  7. java socket 重连复用_Java Socket编程基础及深入讲解(示例代码)

    Socket是Java网络编程的基础,了解还是有好处的, 这篇文章主要讲解Socket的基础编程.Socket用在哪呢,主要用在进程间,网络间通信.本篇比较长,特别做了个目录: 一.Socket通信基 ...

  8. java的尝试性问题_Java并发编程实战 03互斥锁 解决原子性问题

    文章系列 摘要 在上一篇文章02Java如何解决可见性和有序性问题当中,我们解决了可见性和有序性的问题,那么还有一个原子性问题咱们还没解决.在第一篇文章01并发编程的Bug源头当中,讲到了把一个或者多 ...

  9. java 并发框架源码_Java并发编程高阶技术-高性能并发框架源码解析与实战

    Java并发编程高阶技术-高性能并发框架源码解析与实战 1 _0 Z' @+ l: s3 f6 r% t|____资料3 Z9 P- I2 x8 T6 ^ |____coding-275-master ...

最新文章

  1. Oracle学习笔记:redo重做日志
  2. 《计算机组成与设计(ARM版)》读书笔记-第二章指令2
  3. mysql空洞_optimize table 删除空洞--MYSQL
  4. PHP中oop面向对象基础知识(一)
  5. eclipse在server中tomcat server找不到的问题
  6. 灵魂拷问,SQL 查询语句先执行 SELECT吗?
  7. 2021年甘肃省高考成绩一分一段表查询,2021年甘肃高考一分一段表公布查询时间 什么时候出...
  8. 找不到MSVCR120.dll,无法执行代码 ——问题解决方案
  9. 集合综合案例:播放器
  10. tig git的好搭档
  11. IE6,IE7和firefox的兼容问题大集合
  12. 配置高可用Eureka Server遇到的神坑:无法注册服务
  13. Eclipse背景颜色修改
  14. word表批量处理小技巧(python+宏)
  15. pringboot餐饮点餐系统毕业设计源码301749
  16. 五行Python代码实现春节微信祝福神器(基于itchat)
  17. SAM9G45死机问题
  18. 【思维导图】零基础如何把握Python学习方向
  19. H3C 交换机配置命令详解
  20. Amlogic android7.1 s905x hdmi相关内容浅析

热门文章

  1. 【Boost】Boost使用几条简单笔记
  2. 0到1:闲鱼高复杂度高性能社区圈子开发实录
  3. 小红书推荐大数据在阿里云上的实践
  4. 赋能尖端科技 推进智能布局 |《HPC高性能计算数据存储解决方案蓝皮书》正式发布
  5. 基于函数计算的 Serverless AI 推理
  6. 用Flink取代Spark Streaming!知乎实时数仓架构演进
  7. 关于机器学习,你需要知道的三件事!
  8. 漫画:什么是 “元宇宙” ?
  9. 光进铜退下的“更高”与“更低”,锐捷发布企业极简以太全光网解决方案
  10. “编程能力差,90%输在了数学上!”CTO:多数程序员都是瞎努力!