java线程同步

(a).重入方面其内部的WriteLock可以获取ReadLock,但是反过来ReadLock想要获得WriteLock则永远都不要想。

(b).WriteLock可以降级为ReadLock,顺序是:先获得WriteLock再获得ReadLock,然后释放WriteLock,这时候线程将保持Readlock的持 有。反过来ReadLock想要升级为WriteLock则不可能,为什么?参看(a),呵呵.

(c).ReadLock可以被多个线程持有并且在作用时排斥任何的WriteLock,而WriteLock则是完全的互斥。这一特性最为重要,因为对于高 读取频率而相对较低写入的数据结构,使用此类锁同步机制则可以提高并发量。

(d).不管是ReadLock还是WriteLock都支持Interrupt,语义与ReentrantLock一致。

(e).WriteLock支持Condition并且与ReentrantLock语义一致,而ReadLock则不能使用Condition,否则抛出 UnsupportedOperationException异常。
class CachedData{ ReentrantReadWriterLock有锁降级机制,写锁是exclusive锁,读锁是share锁,如果一个线程拿到了写锁,那么它还可以继续拿到读锁
	Object data;
	volatile boolean cacheValid;
	ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();

	void processCachedData() {
		rwl.readLock().lock();
		if (!cacheValid) {
			// Must release read lock before acquiring write lock
			rwl.readLock().unlock();
			rwl.writeLock().lock();
			// Recheck state because another thread might have acquired
			// write lock and changed state before we did.
			if (!cacheValid) {
				 data = ...
				 cacheValid = true;
			}
			// Downgrade by acquiring read lock before releasing write lock
			rwl.readLock().lock();
			rwl.writeLock().unlock(); // Unlock write, still hold read
		}
		use(data);
		rwl.readLock().unlock();
	}
}

这个降级的机制可能保证缓存中get操作的场景的原子性。

举例子。我想get操作的时候,发现数据已经失效,需要用新数据覆盖失效数据,并返回最新结果。这个场景用锁降级可以保证。当然用synchronized可以实现,只是那样的话就用不到读写锁的读读不互斥的优点了(转入正题)。

用大师的这个加锁顺序:
        rwl.writeLock().lock();
        rwl.readLock().lock();
        rwl.writeLock().unlock(); 
        rwl.readLock().unlock();
看出来了没?如果一个线程拿到了写锁,即使更新缓存的动作做完了,再拿到读锁,准备返回数据。这样可以保证返回的数据是这次更新的数据。如果没有这个降级机制的话,在释放了读锁之后,可能会被另外一个线程抢到读锁,继续更新缓存,再返回的数据就不是第一次更新的数据了。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值