互斥锁、读写锁
ReentrantLock 和 ReentrantReadWriteLock
JDK5增加了ReentrantLock这个类因为两点:
1.ReentrantLock提供了tryLock方法,tryLock调用的时候,如果锁被其他线程(同一个线程两次调用tryLock也都返回true)持有,那么tryLock会立即返回,返回结果是false。lock()方法会阻塞。
2.构造RenntrantLock对象可以接收一个boolean类型的参数,描述锁公平与否的函数。公平锁的好处是等待锁的线程不会饿死,但是整体效率相对低一些;非公平锁的好处是整体效率相对高一些。
注意:使用ReentrantLock后,需要显式地进行unlock,所以建议在finally块中释放锁,如下:
lock.lock(); try { //do something } finally { lock.unlock(); } |
ReentrantReadWriteLock与ReentrantLock的用法类似,差异是前者通过readLock()和writeLock()两个方法获得相关的读锁和写锁操作。
原子数
除了用互斥锁控制变量的并发修改之外,jdk5中还增加了原子类,通过比较并交换(硬件CAS指令)来避免线程互斥等待的开销,进而完成超轻量级的并发控制,一般用来高效的获取递增计数器。
AtomicInteger counter = new AtomicInteger();
counter.incrementAndGet();
counter.decrementAndGet();
可以简单的理解为以下代码,增加之后与原先值比较,如果发现增长不一致则循环这个过程。代码如下
public class CasCounter { private SimulatedCAS value; public int getValue() { return value.getValue(); } public int increment() { int oldValue = value.getValue(); while (value.compareAndSwap(oldValue, oldValue + 1) != oldValue) oldValue = value.getValue(); return oldValue + 1; } } |
可以看IBM工程师的一篇文章 Java 理论与实践: 流行的原子