等待锁和等待条件、临界区实现、读写锁实现

本文深入探讨了读写锁的模拟实现,包括条件/同步状态、锁和信号三个要素,并通过代码展示了如何使用条件等待来模拟锁的行为。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

之前总结过,线程的暂停只有两种可能,等待锁(lock.lock(), synchronized(lock))和等待条件(condition.await(), object.wait())

其他的synchronizer,比如CountDownLatch, Barrier,BlockingQueue等,都是基于等待条件的,可以用condition实现。而condition又以锁为基础,condition是共享数据,访问(check 和update)必须在锁里。


问题来了,锁本身其实又是基于某种condition, 就是进入临界区的线程数count,当count == 0可以进入,否则不能进入。这个condition如何保护?可以假想一下可能的实现

1)CAS + 自旋:

2)CAS + 等待


读写锁也是一种条件:是否有写线程在等待,writeCount > 0, 这个条件为真前,都可以进入,同时,读线程不更新这个条件,写线程更新条件。

下面是一个读写锁的模拟实现,可以看到同步器的三要素

1)条件/同步状态:线程是否可以继续的依据(readCount,writeCount)

2)锁:保护同步状态的读写(ReentrantLock lock)

3)信号:使得线程等待,或者唤醒信号上等待的线程(readSignal, writeSignal)


外面的try/finally是保证unlock被调用;里面的try/catch是为了保证等待不被interrupt,因为我们要实现的是锁,锁上的等待(比如synchronized块)一般是不可interrupt的,而等待条件是可以interrupt的,本例子是用条件的等待模拟实现锁。

class MyReadWriteLock {
	ReentrantLock lock = new ReentrantLock();
	Condition readSignal = lock.newCondition();
	Condition writeSignal = lock.newCondition();
	
	int writeCount = 0, readCount = 0;
	
	class ReadLock implements Lock {
		@Override
		public void lock() {
			try {
				lock.lock();		
				while (writeCount > 0) {
					try {
						readSignal.await();
					}
					catch (InterruptedException e) {
						Thread.currentThread().interrupt();
					}
				}			
				++readCount;
			}			
			finally {
				lock.unlock();
			}
		}
		@Override 
		public void unlock() {
			try {
				lock.lock();
				if (readCount > 0) --readCount;
				writeSignal.signalAll();
			}
			finally {
				lock.unlock();
			}
		}
	}
	class WriteLock implements Lock {
		@Override
		public void lock(){
			try {
				lock.lock();			
				while (readCount > 0 || writeCount > 0 ) {
					try {
						writeSignal.await();
					}
					catch (InterruptedException e) {
						Thread.currentThread().interrupt();
					}
				}
				++writeCount;
			}			
			finally {
				lock.unlock();
			}
		}
		@Override 
		public void unlock() {
			try {
				lock.lock();
				if (writeCount > 0) --writeCount;
				readSignal.signalAll();
				writeSignal.signalAll();
			}
			finally {
				lock.unlock();
			}
		}
	}
	Lock readLock() {
		return new ReadLock();
	}
	Lock WriteLock() {
		return new WriteLock();
	}
}








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值