multi-thread(七)ReentrantReadWriteLock

被加锁的对象是共享数据,不是线程

1,put,get方法入口处设置断点,debug验证:可以同时有2个读线程,但最多只能有一个写线程

2,用ReentrantReadWriteLock实现线程安全的cache

/**
 * @author timeriver.wang
 * @date 2014-03-10 1:37:11 PM
 */
public class ReadWriteLockTest {
	public static void main(String[] args) {
		final Queue3 q3 = new Queue3();
		for(int i=0;i<2;i++){
			new Thread("r-"+i){
				public void run(){
					while(true){
						q3.get();						
					}
				}
			}.start();
			new Thread("w-"+i){
				public void run(){
					while(true){
						q3.put(new Random().nextInt(10000));
					}
				}			
			}.start();
		}
	}
}

class Queue3{
	private Object data = null;//共享数据,只能有一个线程能写该数据,但可以有多个线程同时读该数据。
	ReadWriteLock rwl = new ReentrantReadWriteLock();
	public void get(){
		rwl.readLock().lock();
		try {
			System.out.println(Thread.currentThread().getName() + " be ready to read data!");
			//验证,多个读线程可以并发读数据。******************************重要!!!!!!
			Thread.sleep((long)(Math.random()*1000));
			System.out.println(Thread.currentThread().getName() + " have read data :" + data);			
		} catch (InterruptedException e) {
			e.printStackTrace();
		}finally{
			rwl.readLock().unlock();
		}
	}
	
	public void put(Object data){
		rwl.writeLock().lock();
		try {
			System.out.println(Thread.currentThread().getName() + " be ready to write data!");					
			Thread.sleep((long)(Math.random()*1000));
			this.data = data;		
			System.out.println(Thread.currentThread().getName() + " have write data: " + data);					
		} catch (InterruptedException e) {
			e.printStackTrace();
		}finally{
			rwl.writeLock().unlock();
		}
	}
}

 2 线程安全的cache

/**
 * @author timeriver.wang
 * @date Mar 10, 2014 3:26:15 PM
 */
public class MyThreadSafeCache {
	private Map<String,Object> cache = new HashMap<String,Object>();
	private ReadWriteLock rwl = new ReentrantReadWriteLock();
	public static void main(String[] args) {
		System.out.println(new MyThreadSafeCache().getData("java"));
	}
	
	public Object getData(String key){
		rwl.readLock().lock();
		Object value = null;
		try {
			value = cache.get(key);
			if(value == null){
				rwl.readLock().unlock();
				rwl.writeLock().lock();
				value = "aaa";
				cache.put("java", value);
				    //本方法的最终目的是read,现在还没有get到数据,还需要占用readLock
					//把读锁提前,可以保证还是当前线程在执行(占用cpu)
					rwl.readLock().lock();
					rwl.writeLock().unlock();
			}
			return value;
		}finally{
			rwl.readLock().unlock();
		}
	}
}

 

猜你喜欢

转载自luckywnj.iteye.com/blog/2028811