Java并发编程系列 concurrent包概览

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java并发编程系列 concurrent包概览相关的知识,希望对你有一定的参考价值。

从JDK 1.5开始,增加了java.util.concurrent包,concurrent包的引入大大简化了多线程程序的开发。

查看JDK的API可以发现,java.util.concurrent包分成了三个部分,
分别是java.util.concurrent、java.util.concurrent.atomic和java.util.concurrent.lock

>>Atomic包

API中的说明是“A small toolkit of classes that support lock-free thread-safe programming on single variables”。
atomic包方便程序员在多线程环境下,无锁的进行原子操作。
原子变量的底层使用了处理器提供的原子指令,但是不同的CPU架构可能提供的原子指令不一样,也有可能需要某种形式的内部锁,所以该方法不能绝对保证线程不被阻塞。
原子变量类相当于一种泛化的volatile变量,能够支持原子的和有条件的读-改-写操作。
在Atomic包里一共有12个类,四种原子更新方式,分别是原子更新基本类型,原子更新数组,原子更新引用和原子更新字段。

Atomic包里的类基本都是使用Unsafe实现的包装类。

(1)标量类(Scalar):AtomicBoolean,AtomicInteger,AtomicLong,AtomicReference
AtomicBoolean,AtomicInteger,AtomicLong,AtomicReference这四种基本类型用来处理布尔,整数,长整数,对象四种数据,其内部实现不是简单的使用synchronized,而是一个更为高效的方式CAS(compareandswap)+volatile和native方法,从而避免了synchronized的高开销,执行效率大为提升。
他们的实现都是真正的值为volatile类型,通过Unsafe包中的原子操作实现。最基础就是CAS,他是一切的基础。其中offset是在内存中value相对于基地址的偏移量。(它的获得也由Unsafe本地代码获得)。
核心代码如下,其他都是在compareAndSet基础上构建的。

privatestaticfinalUnsafeunsafe=Unsafe.getUnsafe();
privatevolatileintvalue;
publicfinalintget(){
returnvalue;
}
publicfinalvoidset(intnewValue){
value=newValue;
}
publicfinalbooleancompareAndSet(intexpect,intupdate){
returnunsafe.compareAndSwapInt(this,valueOffset,expect,update);
}

 

(2)数组类:AtomicIntegerArray,AtomicLongArray,AtomicReferenceArray
AtomicIntegerArray,AtomicLongArray还有AtomicReferenceArray类进一步扩展了原子操作,对这些类型的数组提供了支持。
同样是使用Unsafe类完成的。

(3)更新器类:AtomicLongFieldUpdater,AtomicIntegerFieldUpdater,AtomicReferenceFieldUpdater
基于反射的实用工具,可以对指定类的指定volatile字段进行原子更新。

(4)复合变量类:AtomicMarkableReference,AtomicStampedReference

>>多线程基础包

java.util.concurrent包下面的类和接口定义了JDK1.5以后编写多线程程序能用到的方法等。
(1)常用的接口方法
BlockingQueue和BlockingDeque阻塞队列和双端阻塞队列
Executor:具体Runnable任务的执行者
ExecutorService : 一个线程池管理者,其实现类有多种,可以把Runnable,Callable提交到池中让其调度
ScheduledExecutorService :一个 ExecutorService的子接口,可安排在给定的延迟后运行或定期执行的命令
Future:Future 表示异步计算的结果

(2)实现类概览
CountDownLatch: 一个线程调用await方法以后,会阻塞地等待计数器被调用countDown直到变成0,功能上和下面的CyclicBarrier有点像
CyclicBarrier: 一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点
Semaphore :一个计数信号量]

 

>>lock及其相关应用

位于java.util.concurrent.locks 包下面,主要与新的并发加锁有关系。

(1)接口方法
Condition接口:Lock 实现提供了比使用 synchronized 方法和语句可获得的更广泛的锁定操作。有两个实现类,都是以公开内部类的形式实现的,AbstractQueuedLongSynchronizer.ConditionObject, AbstractQueuedSynchronizer.ConditionObject
Lock接口:有三个实现类,ReentrantLock, ReentrantReadWriteLock.ReadLock, ReentrantReadWriteLock.WriteLock
ReadWriteLock接口:ReadWriteLock 维护了一对相关的锁,一个用于只读操作,另一个用于写入操作。只要没有 writer,读取锁可以由多个 reader 线程同时保持。写入锁是独占的。
与互斥锁相比,读-写锁允许对共享数据进行更高级别的并发访问。虽然一次只有一个线程(writer 线程)可以修改共享数据,但在许多情况下,任何数量的线程可以同时读取共享数据(reader 线程),读-写锁利用了这一点。实现类只有一个,ReentrantReadWriteLock 。
(2)实现类概览
ReentrantLock:一个可重入的互斥锁 Lock。
ReentrantReadWriteLock:可重入的读写锁。
还有几个,这么学习好抽象。

 

参考 Java中的Atomic包使用指南 

 

以上是关于Java并发编程系列 concurrent包概览的主要内容,如果未能解决你的问题,请参考以下文章

深入理解java:2.3.1. 并发编程concurrent包 之Atomic原子操作

深入理解java:2.3.3. 并发编程concurrent包 之容器ConcurrentHashMap

Java并发系列[1]----AbstractQueuedSynchronizer源码分析之概要分析

深入理解java:2.3.4. 并发编程concurrent包 之容器ConcurrentLinkedQueue

☕Java深层系列「并发编程系列」让我们一起探索一下CyclicBarrier的技术原理和源码分析

java.util.concurrent并发包结构锁——博客地址