StampedLock java1.8提供的, 性能比ReadWriteLock好.
final StampedLock sl = new StampedLock(); /** * 悲观读锁 * 与ReadWriteLock的读锁相似 * 允许多个线程进行读操作 * 与写锁互斥 **/ //获取悲观锁 long stamp = sl.readLock(); try { //。。。。 }finally { sl.unlockRead(stamp); } /** * 写锁 * 与ReadWriteLock的写锁相似 * 只允许一个线程进行写操作 * 与读锁互斥 **/ //获取写锁 long stamp1 = sl.writeLock(); try{ //。。。 }finally { //释放写锁 sl.unlockWrite(stamp1); } /** * 乐观读锁升级为悲观读 * 锁的严苛程度变强叫做升级,反之叫做降级 **/ //获取乐观锁 long stamp = sl.tryOptimisticRead(); //判断执行读操作期间,是否存在写操作,如果存在则sl.validate返回false if (!sl.validate(stamp)){ //升级为悲观锁 stamp = sl.readLock(); try{ //。。。 }finally { //释放悲观读锁 sl.unlockRead(stamp); }
StampedLock提供的乐观读,是允许一个线程获取写锁的,也就是说不是所有的写操作都是被阻塞的。
乐观读和乐观锁是不一样的,乐观读这个操作是无锁的,乐观读认为读的时候不会有写的操作。
import java.util.concurrent.locks.StampedLock; /** * 悲观锁乐观锁 **/ public class Point { private int x; private int y; final StampedLock sl = new StampedLock(); //计算到原点的距离 int distanceFromOrigin() throws Exception{ //乐观锁 long stamp = sl.tryOptimisticRead(); //读入局部变量,读的过程数据可能被修改 int curX = x; int curY = y; //判断执行读操作期间,是否存在写操作,如果存在则sl.validate返回false if (!sl.validate(stamp)){ //升级为悲观锁 stamp = sl.readLock(); try{ curX = x; curY = y; }finally { //释放悲观读锁 sl.unlockRead(stamp); } } return (int)Math.sqrt(curX*curX + curY*curY); } }