原文出处: http://www.cnblogs.com/davidwang456/p/4670777.html
第一类:原子操作类的 atomic 包
这个包里面提供了一组原子变量类。其基本的特性就是在多线程环境下,当有多个线程同时执行这些类的实例包含的方法时,具有排他性,即当某个线程进入方法,执行其中的指令时,不会被其他线程打断,而别的线程就像自旋锁一样,一直等到该方法执行完成,才由JVM从等待队列中选择一个另一个线程进入,这只是一种逻辑上的理解。实际上是借助硬件的相关指令来实现的,不会阻塞线程(或者说只是在硬件级别上阻塞了)。可以对基本数据、数组中的基本数据、对类中的基本数据进行操作。原子变量类相当于一种泛化的volatile变量,能够支持原子的和有条件的读-改-写操作。
java.util.concurrent.atomic中的类可以分成4组:
标量类(Scalar):AtomicBoolean,AtomicInteger,AtomicLong,AtomicReference
数组类:AtomicIntegerArray,AtomicLongArray,AtomicReferenceArray
更新器类:AtomicLongFieldUpdater,AtomicIntegerFieldUpdater,AtomicReferenceFieldUpdater
复合变量类:AtomicMarkableReference,AtomicStampedReference
第一组 AtomicBoolean,AtomicInteger,AtomicLong,AtomicReference
这四种基本类型用来处理布尔,整数,长整数,对象四种数据,其内部实现不是简单的使用synchronized,而是一个更为高效的方式CAS (compare and swap) + volatile和native方法,从而避免了synchronized的高开销,执行效率大为提升。如AtomicInteger的实现片断为:
private static final Unsafe unsafe = Unsafe.getUnsafe();
private volatile int value;
public final int get() {
return value;
}
public final void set(int newValue) {
value = newValue;
}
public final boolean compareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
-
构造函数(两个构造函数)
默认的构造函数:初始化的数据分别是false,0,0,null
带参构造函数:参数为初始化的数据
set() 和 get() 方法:可以原子地设定和获取 atomic 的数据。类似于 volatile ,保证数据会在主存中设置或读取
void set() 和 void lazySet():set 设置为给定值,直接修改原始值;lazySet 延时设置变量值,这个等价于 set() 方法,但是由于字段是 volatile 类型的,因此次字段的修改会比普通字段(非 volatile 字段)有稍微的性能延时(尽管可以忽略),所以如果不是想立即读取设置的新值,允许在“后台”修改值,那么此方法就很有用。
-
getAndSet() 方法
原子的将变量设定为新数据,同时返回先前的旧数据
其本质是get( )操作,然后做set( )操作。尽管这2个操作都是atomic,但是他们合并在一起的时候,就不是atomic。在Java的源程序的级别上,如果不依赖synchronized的机制来完成这个工作,是不可能的。只有依靠native方法才可以。
第二组AtomicIntegerArray,AtomicLongArray, AtomicReferenceArray类
这些类进一步扩展了原子操作,对这些类型的数组提供了支持。这些类在为其数组元素提供 volatile 访问语义方面也引人注目,这对于普通数组来说是不受支持的。
他们内部并不是像 AtomicInteger 一样维持一个 valatile 变量,而是全部由 native 方法实现,如下
AtomicIntegerArray 的实现片断:
private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final int base = unsafe.arrayBaseOffset(int[].class);
private static final int scale = unsafe.arrayIndexScale(int[].class);
private final int[] array;
public final int get(int i) {
return unsafe.getIntVolatile(array, rawIndex(i));
}
public final void set(int i, int newValue) {
unsafe.putIntVolatile(array, rawIndex(i), newValue);
}
第三组AtomicLongFieldUpdater,AtomicIntegerFieldUpdater,AtomicReferenceFieldUpdater
基于反射的实用工具,可以对指定类的指定 volatile 字段进行原子更新。API非常简单,但是也是有一些约束:
字段必须是volatile类型的
字段的描述类型(修饰符public/protected/default/private)是与调用者与操作对象字段的关系一致。也就是说 调用者能够直接操作对象字段,那么就可以反射进行原子操作。但是对于父类的字段,子类是不能直接操作的,尽管子类可以访问父类的字段。
只能是实例变量,不能是类变量,也就是说不能加static关键字。
只能是可修改变量,不能使final变量,因为final的语义就是不可修改。实际上final的语义和volatile是有冲突的,这两个关键字不能同时存在。
对于AtomicIntegerFieldUpdater 和AtomicLongFieldUpdater 只能修改int/long类型的字段,不能修改其包装类型(Integer/Long)。如果要修改包装类型就需要使用AtomicReferenceFieldUpdater 。
netty5.0中类ChannelOutboundBuffer统计发送的字节总数,由于使用volatile变量已经不能满足,所以使用AtomicIntegerFieldUpdater 来实现的,看下面代码:
第二类:关于锁的类包
排他锁:AbstractOwnableSynchronizer、AbstractQueuedLongSynchronizer、AbstractQueuedSynchronizer
读写锁、可重入锁:ReadWriteLock、ReentrantLock、Lock、ReentrantReadWriteLock(隐式包含读锁和写锁)、Condition、LockSupport
混合锁:StampedLock
condition 相似于对象的监控方法object#wait()、object#notify、object#notifyAll,但不同之处在于:通过和任意Lock的实现类联合使用,Condition对每个对象提供了多个等待-设置功能。
此时Lock代替了synchronized方法和模块,condition代替了对象的监控方法。
Condition通常也称作Condition队列或者condition变量,它提供了一种方法,使一个线程能够暂停执行(wait方法),当别的线程的状态condition为true时可以激活此线程。由于不同线程共享的状态信息必须受到保护,因此Condition具有一些锁的形式。等待一个condition的关键属性是自动释放关联的锁并且暂停当前线程,类似于object.wait。
Conditon示例内部绑定了一个锁,获取一个特定锁的实例的Condition实例可以通过lock#newCondition方法得到。
ReentrantReadWriteLock的读锁与写锁
读锁是排写锁操作的,读锁不排读锁操作,多个读锁可以并发不阻塞。在读锁获取和读锁释放之前,写锁并不能被任何线程获取。多个读锁同时作用期间,试图获取写锁的线程都处于等待状态,当最后一个读锁释放后,试图获取写锁的线程才有机会获取写锁。
写锁是排写锁,排读锁操作的。当一个线程获取到写锁之后,其他试图获取写锁和试图获取读锁的线程都处于等待状态,直到写锁被释放。
同时,写锁中是可以获取读锁,但是读锁中是无法获取写锁的。
第三类:并发数据结构
阻塞数据结构:ArrayBlockingQueue、BlockingDeque、BlockingQueue、LinkedBlockingDeque、LinkedBlockingQueue、PriorityBlockingQueue、
并发数据结构:ConcurrentHashMap、ConcurrentLinkedDeque、ConcurrentLinkedQueue、ConcurrentMap、ConcurrentNavigableMap、ConcurrentSkipListMap、ConcurrentSkipListSet
第四类:同步器
这部分主要是对线程集合的管理的实现,有Semaphore,CyclicBarrier, CountDownLatch,Exchanger等一些类。