特色:html
不适用的场景:java
场景一:变量用于非原子的操做编程
private volatile int count; public void increment() { count++; }
++操做不是原子操做,volatile不能保证数据的原子性。若是须要原子的读写操做,可使用concurrent包里的AtomicXxx类。缓存
场景二:变量与其它变量在一个不变式条件中(以下:lower < upper是一个不变式)多线程
public class NumberRange { private int lower, upper; public int getLower() { return lower; } public int getUpper() { return upper; } public void setLower(int value) { if (value > upper) throw new IllegalArgumentException(...); lower = value; } public void setUpper(int value) { if (value < lower) throw new IllegalArgumentException(...); upper = value; } }
多线程状况下,若是两个线程同时修改lower和upper,这时候即便是volatile也不能保证lower < upper这个不变式始终成立。并发
场景三:变量须要加锁访问的状况,由于已经用了锁,volatile显然是多余的。jvm
特色:性能
一种轻量级的锁,基于硬件CPU指令实现。这是一种乐观锁,假设不会产生冲突而不加锁地进行操做,若是操做失败就不停地重试,直到操做成功。是一种非阻塞的机制。优化
原理:提供3个操做数,分别是内存位置V,原有的预期值A,要修改的新值B,只有当A=V时,才把V的值修改成B,不然,一直重试,直到成功。.net
public final int incrementAndGet() { for (;;) { int current = get(); int next = current + 1; if (compareAndSet(current, next)) return next; } }
问题:
特色:
特色:
特色:
无论是synchronized仍是ReentrantLock,都是强类型的互斥锁,并发状况下的性能会受影响。可是在一些应用场景下,可能读操做要多于写操做,在没有写操做的时候,若是用这种强互斥锁的话,会严重影响读线程的性能。因此能够考虑用ReentrantReadWriteLock来代替上面的强互斥锁,让多个读线程能够并发地访问被保护的对象,提升吞吐量。PS:能够在LinkedHashMap上使用ReentrantReadWriteLock来实现高性能的LRU Cache.
另一种读写锁的实现是经过volatile(保证读可见) + synchronized(保证写原子性)来实现。
参考资料:
推荐阅读: