讀寫鎖ReentrantReadWriteLock

實例:

public class ReentrantReadWriteLockTest {
	private static ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
	//private static ReentrantLock lock = new ReentrantLock();
	private static ReadLock readLock = lock.readLock();
	private static WriteLock writeLock = lock.writeLock();
	private static Map<String,String> map = new HashMap<String,String>();

	//減數門栓,減爲零後就不計算了
	private static CountDownLatch latch = new CountDownLatch(102);

	//週期循環的屏障。加到102後,從0開始計算
	private static CyclicBarrier barrier = new CyclicBarrier(102);
	
	
	public static void main(String[] args) throws InterruptedException{
		
		long beginTime = System.currentTimeMillis();
		
		
		for(int i = 0 ; i < 100 ; i++){
			new Thread(new ReadThread()).start();
		}
		for(int i = 0 ; i < 2 ; i++){
			new Thread(new WriteThread()).start();
		}
		latch.await();
		long endTime = System.currentTimeMillis();
		
		System.out.println("一共使用了" + (endTime-beginTime) + "ms");
		
	}

	static class WriteThread implements Runnable{
		public void run(){
			try {
				//相當於把所用讀寫線程放到同一水平線上在開始真正的計算
				barrier.await();
			}
			catch (Exception e) {
				e.printStackTrace();
			}

			try {
				//加在對象上的鎖
				writeLock.lock();
				//lock.lock();
				map.put("1", "2");
				Thread.sleep(100);			}
			catch (Exception e) {
				e.printStackTrace();
			}
			finally{
				writeLock.unlock();

				//lock.unlock();
			}
			//latch把計數加一
			latch.countDown();


		}
	}
	
	
	
	
	static class ReadThread implements Runnable{
		public void run(){
			try {
				//相當於把所用讀寫線程放到同一水平線上在開始真正的計算
				barrier.await();
			}
			catch (Exception e) {
				e.printStackTrace();
			}

			try {
				//加在ReentrantReadWriteLockTest對象上的鎖
				readLock.lock();
				//lock.lock();
				//System.out.println(this.toString());
				map.get("1");
				Thread.sleep(100);			}
			catch (Exception e) {
				e.printStackTrace();
			}
			finally{
				readLock.unlock();
				//lock.unlock();

			}
			latch.countDown();


		}
	}
}

注意:

1)讀鎖和寫鎖就是一個鎖的不同視圖,所以他和ReentrantLock類似都有可重入的語義。
2)同一個線程實現獲得讀鎖的時候,再次想獲取寫鎖的話,就會產生死鎖,那麼叫做不可升級。
3)同一個線程實現獲得寫鎖的時候,可以再次獲取讀鎖的話(lock.lock),不會產生死鎖,但是在最後寫鎖的釋放就會把當前鎖降級爲讀鎖。
4)在讀多寫少的情況下,性能迴避ReentrantLock這樣的硬性加鎖性能有很大的提升,不然的話性能就會低,因爲讀寫鎖的實現更爲複雜。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章