實例:
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這樣的硬性加鎖性能有很大的提升,不然的話性能就會低,因爲讀寫鎖的實現更爲複雜。