Concurrent包第二部分

一、CyclicBarrier栅栏

1、栅栏概述
  Concurrent包中提供的一种并发构造,可以实现多个并发的线程在执行过程中,在某一个节点进行阻塞等待,直到所有的线程都到达了指定位置后,一起放开阻塞继续运行的效果。例子:赛马。

2、API

CyclicBarrier(int parties):
构造方法,接收一个初始值,指定了栅栏要等待的线程的数量。通过创建一个新的 CyclicBarrier,它将在给定数量的参与者(线程)处于等待状态时启动。
当线程到达了栅栏时,可以调用此方法,进入阻塞等待的状态,线程被挂起,直到在栅栏上等待的线程的数量达到了栅栏上设定的要等待的线程的数量,所有线程的阻塞同时被放开,一起继续执行。

await() :

在所有参与者都已经在此 barrier 上调用 await 方法之前,将一直等待。

二、Exchanger交换机

1、交换机概述
可以实现两个线程交换对象的效果,先到达的线程会产生阻塞等待后续到来的线程,直到两个线程都到达交换机后,互换对象,各自继续执行。

2、API

exchanger() 

构造方法。
在交换机中交换对象的方法,先到的线程调用此方法时,会进入阻塞状态,直到另一个线程也调用这个方法,互换对象,阻塞放开,各自继续执行。

exchange(V x) 

等待另一个线程到达此交换点(除非当前线程被中断),然后将给定的对象传送给该线程,并接收该线程的对象。

三、Semaphore信号量

1、信号量概述
Concurrent包中提供的一个并发构造,可以在创建信号量时指定信号量的初始数量,后续可以调用acquire()来获取信号量,通过release()释放信号量,如果某一个时刻,信号量被取完,再调用acquire()方法时,该方法将会产生阻塞,直到有其他线程release()信号量回来。

2、信号量的主要用途
(1)保护一个重要代码,防止一次超过 N 个线程进入。
(2)在两个线程之间发送信号。

3、API
构造方法,在构造的时候需要指定信号量的初始值,可选的还可以传入一个布尔类型的值,来指定当前信号量是否采用公平策略,默认是不公平的。
补充:
不公平策略就是不管哪个线程是先来的,哪个线程是后到的,一有资源,让他们抢占。相反,公平策略就是把资源分配给先到先等带的线程。
Semaphore(int permits) 创建具有给定的许可数和非公平的公平设置的信号量。
Semaphore(int permits, boolean fair) 创建具有给定的许可数和给定的公平设置的 信号量。

acquire() 从此信号量获取一个许可,在提供一个许可前一直将线程阻塞,否则线程被中断。获得信号量,在信号量上数量-1,如果已经没有剩余的信号量,则此方法将会阻塞,直到有其他线程释放信号量。

release() 释放一个许可,将其返回给信号量。 释放信号量,在信号量上数量+1。
4、案例

四、Atmoic原子性

在java中最基本的运算都是非原子性的,在底层存在多个步骤,所以在多线程并发操作的过程中有可能有多线程并发安全问题。

解决方案有两种:
解决方案1:
使用同步代码块进行同步,可以解决问题,但是如果在多线程并发场景下,最基本的运算都要同步的话,代码会被大量的同步代码块包裹,代码混乱,效率低下。

解决方案2:
使用Concurrent包中提供的Atomic原子型操作。

1、Atomic原子型操作
为了解决以上问题,在Concurrent包中,提供了大量可以实现原子型操作的包装类型

java.util.concurrent.atomic 
类 AtomicBoolean

java.util.concurrent.atomic 
类 AtomicInteger

java.util.concurrent.atomic 
类 AtomicLong

java.util.concurrent.atomic 
类 AtomicReference<V>

AtomicInteger为例:

构造方法摘要
AtomicInteger()创建具有初始值 0 的新 AtomicInteger。
AtomicInteger(int initialValue) 创建具有给定初始值的新 AtomicInteger。
int getAndAdd(int delta) 以原子方式将给定值与当前值相加。返回原有值后在原值上加给定值,类似于i++的原理
int getAndIncrement() 以原子方式将当前值加 1,获取原值后在原值上加一
int getAndDecrement() 以原子方式将当前值减 1,获取原值后在原值上减一
void set(int newValue) 设置为给定值。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章