Java 8并发工具包漫游指南(下)

2017-03-19 From 程序之心 By 丁仪

使用锁实现的同步机制很像synchronized块,但是比synchronized块更灵活。锁和synchronized的主要区别在于:

Synchronized块不能保证等待进入块的线程的访问顺序;

Synchronized块无法接收参数,不能在有超时时间限制的情况下尝试访问;

Synchronized块必须包含在单个方法中,而锁的lock和unlock操作可以在单独的方法中。

工具包提供了以下几种类型的锁:

ReadWriteLock:读写锁接口,允许多个线程读取某个资源,但是一次只能有一个线程进行写操作。内部有读锁、写锁两个接口,分别保护读操作和写操作。实现类为ReentrantReadWriteLock。

ReentrantLock:可重入锁,具有与使用 synchronized 方法和语句所访问的隐式监视器锁定相同的一些基本行为和语义,但功能更强大。ReentrantLock 将由最近成功获得锁定,并且还没有释放该锁定的线程所拥有。当锁定没有被另一个线程所拥有时,调用 lock 的线程将成功获取该锁定并返回。如果当前线程已经拥有该锁定,此方法将立即返回。内部有一个计数器,拥有锁的线程每锁定一次,计数器加1,每释放一次计数器减1。

原子类型

工具包提供了一些可以用原子方式进行读写的变量类型,支持无锁线程安全的单变量编程。

本质上,这些类都扩展了volatile的概念,使用一个volatile类型的变量来存储实际数据。

工具包提供了4种类型的原子变量类型:

AtomicBoolean:可原子操作的布尔对象;

AtomicInteger:可原子操作的整形对象;

AtomicLong:可原子操作的长整形对象;

AtomicReference:可原子操作的对象引用。

以AtomicInteger为例。在Java中i++和++i操作并不是线程安全的,需要加锁。AtomicInteger提供了以下几种线程安全的操作方法:

方法

定义

作用

getAndIncrement

public final int getAndIncrement()

i++

getAndDecrement

public final int getAndDecrement()

i--

incrementAndGet

public final int incrementAndGet()

++i

decrementAndGet()

public final int decrementAndGet()

--i

getAndAdd

public final int getAndAdd(int delta)

增加delta返回旧值

addAndGet

public final int addAndGet(int delta)

增加delta返回新值

在此基础上,工具包还提供了原子性的数组类型,包括AtomicIntegerArray、AtomicLongArray、AtomicReferenceArray。

并发工具

CountDownLatch

CountDownLatch用于一个或者多个线程等待一系列指定操作的完成。初始化时,给定一个数量,每调用一次countDown() 方法数量减一。其他线程调用await方法等待时,线程会阻塞到数量减到0才开始执行。

CyclicBarrier 栅栏

CyclicBarrier是一种同步机制,它能够对处理一些算法的线程实现同步。换句话讲,它就是一个所有线程必须等待的一个栅栏,直到所有线程都到达这里,然后所有线程才可以继续做其他事情。在下图的流程中,线程1和线程2都到达第一个栅栏后才能够继续运行。如果线程1先到线程2后到,则线程1需要等待线程2到达栅栏处,然后两个线程才能继续运行。


Exchanger 交换机

Exchanger类表示一种会合点,两个线程可以在这里交换对象。两个线程各自调用exchange方法进行交换,当线程A调用Exchange对象的exchange()方法后,它会陷入阻塞状态,直到线程B也调用了exchange()方法,然后以线程安全的方式交换数据,之后线程A和B继续运行。

Semaphore 信号量

Semaphore 可以很轻松完成信号量控制,Semaphore可以控制某个资源可被同时访问的个数,通过 acquire() 获取一个许可,如果没有就等待,而 release() 释放一个许可。

ThreadLocalRandom产生并发随机数

使用Math.random()产生随机数,使用原子变量来保存当前的种子,这样两个线程同时调用序列时得到的是伪随机数,而不是相同数量的两倍。ThreadLocalRandom提供并发产生的随机数,能够解决多个线程发生的竞争争夺。

本文来源:程序之心,转载请注明出处!

本文地址:https://chengxuzhixin.com/blog/article/200018.html

发表感想

© 2016 - 2022 chengxuzhixin.com All Rights Reserved.

浙ICP备2021034854号-1    浙公网安备 33011002016107号