线程同步机制(二)-- 线程同步辅助类

我们在线程同步机制(一)--Synchronized和Lock简要介绍中学习了同步和临界区的概念,并且讨论了多个并发任务共享一个资源时的同步情况。访问共享资源的代码块叫临界区。

我们在线程同步机制(一)--Synchronized和Lock简要介绍中学习了一下内容:

  • synchronized关键字
  • Lock接口及其实现类,如ReentrantLock,ReentrantReadWriteLock.ReadLock和ReentrantReadWriteLock.WriteLock

本章我们将学习如何使用更高级的同步机制来实现多线程间的同步。

  • 信号量(Semaphore):一种计数器,用来保护一个或多个共享资源的访问。它是并发编程的一个基础工具。
  • CountDownLatch:是Java语言提供的同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许线程一直等待
  • CyclicBarrier:Java语言提供的同步辅助类,允许多个线程在某个集合点处进行相互等待
  • Phaser:它把并发任务分多个阶段运行,在开始下一个阶段之前,当前阶段中所有的线程都必须执行完成。
  • Exchanger:它提供了两个线程之间的数据交换点。

在应用程序中,任何时候都可以使用Semaphore来保护临界区,因为它是一个基础的同步机制。

1、资源的并发访问控制。

Java语言提供了信号量(Semaphore)机制。信号量是一种计数器,用来保护一个或多个共享资源的访问。如果线程要访问一个共享资源,它必须要获得信号量。如果信号量的内部计数器大于0,信号量将减1,然后允许访问这个共享资源。计数器大于0意味着有可以使用的资源,因此线程被允许使用其中一个资源。否则,如果信号的计数器等于0,信号量就会把线程置入休眠直到计数器大于0.计数器等于0的时候意味着所有的共享资源已经被其他线程使用了,所以需要访问这个共享资源的线程必须等待。

当线程使用完某个共享资源时,信号量必须释放,以便其他线程能够访问共享资源。释放操作将使信号量内部计数器增加1.

使用信号量实现临界区必须遵循3个步骤,从而保护对资源的访问。

(1).必须通过acquire()方法获得信号量

(2).使用共享资源执行必要的操作

(3).必须通过release()方法释放信号量

2、等待多个并发事件的完成

Java并发API提供了CountDownLatch类。在完成一组正在其他线程中执行的操作之前,它允许线程一直等待。这个类使用一个整数进行初始化,这个整数是线程要等待完成的操作的数目。当一个线程要等待某些操作先完成时,需要调用await()方法。当一个线程操作完成后,它将调用countDown()方法使内部计数器减1.当计数器变成0的时候,CountDownLatch类将唤醒所有调用await()而进入休眠的线程

CountDownLatch类有三个基本元素:

  • 一个初始值,即定义必须等待的先行完成的操作数据;
  • await()方法,需要等待其他事件先完成的线程调用
  • countDown()方法,每个被等待的事件在完成操作后调用,使内部计数器减1.当内部计数器到达0时,countDownLatch对象将唤醒所有在await()方法上等待的线程

3、并发阶段任务的运行

Java并发API还提供了Phaser,它允许执行并发多阶段任务。当我们有并发任务并且需要分解成几步执行时,这种机制就非常实用。Phaser类机制是在每一步结束的位置对线程进行同步,当所有线程都执行完了这一步,才允许执行下一步。Phaser类提供了onAdvance()方法,它在phaser阶段改变的时候自动执行。

4、并发任务之间的数据交换Exchanger。它允许在并发任务之间的数据交换,具体来说,Exchanger类允许两个线程定义同步点。当两个线程都达到同步点时,他们交换数据结构。

时间: 2024-10-10 08:29:40

线程同步机制(二)-- 线程同步辅助类的相关文章

对JavaScript中异步同步机制以及线程深入底层了解

今天在网上看到各种对Js异步同步单线程多线程的讨论 经过前辈们的洗礼 加上鄙人小小的理解 就来纸上谈兵一下吧~ Js本身就是单线程的 至于为什么Js是单线程的 那就要追溯到Js的历史了 总而言之 由于Js是浏览器的脚本语言 经常操作dom元素 多线程的话反而会导致更复杂(删除与添加同时进行?)这只是简单的解释了为什么Js要单线程的原因, 为什么Js又能异步执行方法呢? 这特么的不是很矛盾吗!!! 但是,但是注意了 就是因为Js主要是在浏览器中运行的脚本语言 浏览器是典型的GUi工作线程 因为它在

分析.Net里线程同步机制

我们知道并行编程模型两种:一种是基于消息式的,第二种是基于共享内存式的. 前段时间项目中遇到了第二种 使用多线程开发并行程序共享资源的问题 ,今天以实际案例出发对.net里的共享内存式的线程同步机制做个总结,由于某些类库的应用属于基础,所以本次不对基本使用做出讲解,基本使用 MSDN是最好的教程. 一.volatile关键字      基本介绍: 封装了 Thread.VolatileWrite() 和  Thread.VolatileRead()的实现 ,主要作用是强制刷新高速缓存.     

java并发:线程同步机制之ThreadLocal

1.简述ThreadLocal ThreadLocal实例通常作为静态的私有的(private static)字段出现在一个类中,这个类用来关联一个线程.ThreadLocal是一个线程级别的局部变量,下面是线程局部变量(ThreadLocal variables)的关键点: A.当使用ThreadLocal维护变量时,若多个线程访问ThreadLocal实例,ThreadLocal为每个使用该变量的线程提供了一个独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其他线程所对应

ThreadLocal共享线程局部变量和线程同步机制的区别

ThreadLocal是解决线程安全问题一个很好的思路,它通过为每个线程提供一个独立的变量副本解决了变量并发访问的冲突问题.在很多情况下,ThreadLocal比直接使用synchronized同步机制解决线程安全问题更简单,更方便,且结果程序拥有更高的并发性. 对于多线程资源共享的问题,同步机制采用了"以时间换空间"的方式,而ThreadLocal采用了"以空间换时间"的方式.前者仅提供一份变量,让不同的线程排队访问,而后者为每一个线程都提供了一份变量,因此可以同

Linux内核同步机制

http://blog.csdn.net/bullbat/article/details/7376424 Linux内核同步控制方法有很多,信号量.锁.原子量.RCU等等,不同的实现方法应用于不同的环境来提高操作系统效率.首先,看看我们最熟悉的两种机制——信号量.锁. 一.信号量 首先还是看看内核中是怎么实现的,内核中用struct semaphore数据结构表示信号量(<linux/semphone.h>中): [cpp] view plaincopyprint? struct semaph

【转】C#异步编程及其同步机制

C#异步编程及其同步机制 本篇文章涵盖一下几部分内容: 1. 什么是异步编程,为什么会需要异步编程 2. .NET下的异步编程及其发展 3. .NET线程同步机制及线程间数据封送 4. 异步模式 5. 线程安全及异常处理 6. 线程取消 什么是异步编程,为什么会需要异步编程 这个世界上资源是受限的.但资源限制和懒惰一样促进了工业和科技的发展.在计算机方面举个例子,计算机非得是二进制吗?对计算机来说二进制最好吗?不是,这是由于当时工业水平限制,把电压分成两份表示0和1比分成三份更加方便且可靠:虚拟

java——同步机制(synchronized, volatile)

1. java的线程间通信是由java的内存模型(JMM)来控制的. JMM(java memory management) 定义了线程和主内存之间的抽象关系,一个是主内存(多线程之间来进行共享),一个是每个线程自己的私有内存 2. 为什么需要同步机制? (1) 同步机制一般发生在多线程中,当需要跨线程维护程序的正确性,当需要多个线程之间共享非final变量时,就必须使用同步机制来保证一个线程的操作对于另一个线程是可见的 (2) 同步机制保证了多个线程之间的可靠通信,保证了多个线程之间对共享变量

多进程间通信方式和多线程同步机制总结

多进程之间通信方式: 文件映射:本地之间 共享内存:本地之间 匿名管道:本地之间 命名管道:跨服务器 邮件槽:一对多的传输数据,通常通过网络向一台Windows机器传输 剪切板:本地之间 socket:跨服务器 多线程之间通信方式: 全局变量 自定义消息响应 多线程之间同步机制:           临界区:不可以跨进程,忘记解锁会无限等待,要么存在要么没有,多线程访问独占性共享资源 互斥量:可以跨进程,忘记解锁会自动释放,要么存在要么没有 事件:又叫线程触发器,不可以跨进程,要么存在要么没有,

JAVA学习篇--ThreadLocal,Java中特殊的线程绑定机制

在DRP项目中,我们使用了ThreadLocal来创建Connection连接,避免了一直以参数的形式将Connection向下传递(传递connection的目的是由于jdbc事务要求确保使用同一个connection连接).那么ThreadLocal是如果做到的呢?它和同步锁的不同在哪里? 是什么: 对于ThreadLocal看英文单词我们很容易理解为一个线程的本地实现,但是它并不是一个Thread,而是threadlocalvariable(线程局部变量).也许把它命名为ThreadLoc

Java-ThreadLocal,Java中特殊的线程绑定机制

在DRP项目中,我们使用了ThreadLocal来创建Connection连接,避免了一直以参数的形式将Connection向下传递(传递connection的目的是由于jdbc事务要求确保使用同一个connection连接).那么ThreadLocal是如果做到的呢?它和同步锁的不同在哪里? 是什么: 对于ThreadLocal看英文单词我们很容易理解为一个线程的本地实现,但是它并不是一个Thread,而是threadlocalvariable(线程局部变量).也许把它命名为ThreadLoc