multi-thread(7)ReentrantReadWriteLock
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(); } } }