WEB开发网
开发学院软件开发Java 多线程基础总结八--ReentrantReadWriteLock 阅读

多线程基础总结八--ReentrantReadWriteLock

 2010-01-22 00:00:00 来源:WEB开发网   
核心提示:说到ReentrantReadWriteLock,首先要做的是与ReentrantLock划清界限,多线程基础总结八--ReentrantReadWriteLock,它和后者都是单独的实现,彼此之间没有继承或实现的关系,否则抛出UnsupportedOperationException异常, 以上就是比较重要的,然后就

说到ReentrantReadWriteLock,首先要做的是与ReentrantLock划清界限。它和后者都是单独的实现,彼此之间没有继承或实现的关系。然后就是总结这个锁机制的特性了:

(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异常。

以上就是比较重要的,或者衡量是否使用ReentrantReadWriteLock的基础了。下面还是写个小例子说明部分内容:

Java代码

import java.util.HashMap; 
import java.util.Map; 
import java.util.concurrent.locks.Lock; 
import java.util.concurrent.locks.ReentrantReadWriteLock; 
 
/** 
 * @author: yanxuxin 
 * @date: 2010-1-7 
 */ 
public class ReentrantReadWriteLockSample { 
 
 public static void main(String[] args) { 
 testReadLock(); 
// testWriteLock(); 
 } 
 
 public static void testReadLock() { 
  final ReadWriteLockSampleSupport support = new ReadWriteLockSampleSupport(); 
 support.initCache(); 
  
 Runnable runnable = new Runnable() { 
  public void run() { 
  support.get("test"); 
  } 
 }; 
  
 new Thread(runnable).start(); 
 new Thread(runnable).start(); 
  
 new Thread(new Runnable() { 
  public void run() { 
  support.put("test", "test"); 
  } 
 }).start(); 
 } 
 
 public static void testWriteLock() { 
  final ReadWriteLockSampleSupport support = new ReadWriteLockSampleSupport(); 
 support.initCache(); 
  
 new Thread(new Runnable() { 
  public void run() { 
  support.put("key1", "value1"); 
  } 
 }).start(); 
  
 new Thread(new Runnable() { 
  public void run() { 
  support.put("key2", "value2"); 
  } 
 }).start(); 
  
 new Thread(new Runnable() { 
  public void run() { 
  support.get("key1"); 
  } 
 }).start(); 
 } 
} 
 
class ReadWriteLockSampleSupport { 
 private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); 
 private final Lock readLock = lock.readLock(); 
 private final Lock writeLock = lock.writeLock(); 
 
 private volatile boolean completed; 
 private Map<String,String> cache; 
 
 public void initCache() { 
 readLock.lock(); 
 if(!completed) { 
  // Must release read lock before acquiring write lock 
  readLock.unlock(); // (1) 
  writeLock.lock(); // (2) 
  if(!completed) { 
  cache = new HashMap<String,String>(32); 
  completed = true; 
  } 
  // Downgrade by acquiring read lock before releasing write lock 
  readLock.lock();  // (3) 
  writeLock.unlock(); // (4) Unlock write, still hold read 
 } 
  
 System.out.println("empty? " + cache.isEmpty()); 
 readLock.unlock(); 
 } 
 
 public String get(String key) { 
 readLock.lock(); 
 System.out.println(Thread.currentThread().getName() + " read."); 
 startTheCountdown(); 
 try{ 
  return cache.get(key); 
 } 
 finally{ 
  readLock.unlock(); 
 } 
 } 
 
 public String put(String key, String value) { 
 writeLock.lock(); 
 System.out.println(Thread.currentThread().getName() + " write."); 
 startTheCountdown(); 
 try{ 
  return cache.put(key, value); 
 } 
 finally { 
  writeLock.unlock(); 
 } 
 } 
 
 /** 
 * A simple countdown,it will stop after about 5s. 
 */ 
 public void startTheCountdown() { 
 long currentTime = System.currentTimeMillis(); 
 for(;;) { 
  long diff = System.currentTimeMillis() - currentTime; 
  if(diff > 5000) { 
  break; 
  } 
 } 
 } 
}

1 2  下一页

Tags:线程 基础 总结

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接