读写锁
ReentrantReadWriteLock
当读操作远远高于写操作时,这时候使用读写锁让读-读可以并发,提高性能。
读读并发:
public static void main(String[] args) {ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();for(int i=0;i<10;i++){new Thread(() -> {rwLock.readLock().lock();try {log.info("读取信息中。。。");Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}finally {rwLock.readLock().unlock();}}).start();}
}
读写不并发:
public static void main(String[] args) {ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();new Thread(() -> {rwLock.writeLock().lock();try {log.info("写入信息中。。。");Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);} finally {rwLock.writeLock().unlock();}}).start();new Thread(() -> {rwLock.readLock().lock();try {log.info("读取信息中。。。");} finally {rwLock.readLock().unlock();}}).start();
}
StampedLock
该类自 JDK 8 加入,是为了进一步优化读性能,它的特点是在使用读锁、写锁时都必须配合【戳】使用
class DataContainerStamped {private int data;private final StampedLock lock = new StampedLock();public DataContainerStamped(int data) {this.data = data;}public int read(int readTime) {long stamp = lock.tryOptimisticRead();log.debug("optimistic read locking...{}", stamp);sleep(readTime);if (lock.validate(stamp)) {log.debug("read finish...{}, data:{}", stamp, data);return data;}// 锁升级 - 读锁log.debug("updating to read lock... {}", stamp);try {stamp = lock.readLock();log.debug("read lock {}", stamp);sleep(readTime);log.debug("read finish...{}, data:{}", stamp, data);return data;} finally {log.debug("read unlock {}", stamp);lock.unlockRead(stamp);}}public void write(int newData) {long stamp = lock.writeLock();log.debug("write lock {}", stamp);try {sleep(2);this.data = newData;} finally {log.debug("write unlock {}", stamp);lock.unlockWrite(stamp);}}
}