package locks; import java.util.Random; import java.util.concurrent.locks.ReentrantReadWriteLock; /* *ReentrantReadWriteLock 读写互斥, *如果读操作被上锁,写操作就不能进行, *如果写操作被上锁,读操作就不能进行, * *读操作上锁后,需要解锁后, 写才能上锁。 * 如果读没有解锁,还调用了写的锁,就会造成堵塞,让线程卡在哪里。 * 反之却是可以的,即在写没有解锁,读操作上锁是可以的。(叫做降级锁) * */ public class ReadWriteLockTest { public static void main(String[] args) { final Queue q3 = new Queue(); // 弄3个读的线程, 弄3个写的线程 for (int i = 1; i <= 3; i++) { new Thread() { public void run() { while (true) { q3.put(new Random().nextInt(10000)); } } }.start(); new Thread() { public void run() { while (true) { q3.get(); } } }.start(); } } } class Queue { private Object data = null; // hibernate load的方法实现就是 ReentrantReadWriteLock 放在代理对象中 private ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); public void get() { rwl.readLock().lock(); try { System.out.println(Thread.currentThread().getName() + "开始取"); Thread.sleep((long) (Math.random() * 1000)); System.out.println(Thread.currentThread().getName() + "取完毕" + data); } catch (InterruptedException e) { e.printStackTrace(); } rwl.readLock().unlock(); } public void put(Object obj) { rwl.writeLock().lock(); try { System.out.println(Thread.currentThread().getName() + "开始写"); Thread.sleep((long) (Math.random() * 1000)); this.data = obj; System.out.println(Thread.currentThread().getName() + "写结束" + obj); } catch (InterruptedException e) { e.printStackTrace(); } rwl.writeLock().unlock(); } }
执行结果:
Thread-1开始取
Thread-1取完毕null
Thread-0开始写
Thread-0写结束4973
Thread-4开始写
Thread-4写结束2476
Thread-3开始取
Thread-3取完毕2476
Thread-2开始写
Thread-2写结束3388
Thread-2开始写
Thread-2写结束2905
Thread-5开始取
Thread-1开始取
Thread-1取完毕2905
Thread-5取完毕2905
Thread-0开始写
Thread-0写结束4504
Thread-4开始写
Thread-4写结束9962
Thread-3开始取
Thread-3取完毕9962
Thread-2开始写
Thread-2写结束3281
Thread-2开始写
Thread-2写结束1530
Thread-1开始取
Thread-5开始取
Thread-5取完毕1530
Thread-1取完毕1530
Thread-0开始写
Thread-0写结束8294
Thread-0开始写
Thread-0写结束7573
Thread-4开始写
Thread-4写结束4506
Thread-4开始写
Thread-4写结束4768
Thread-3开始取
Thread-3取完毕4768
Thread-2开始写
package concurrent; import java.util.HashMap; import java.util.Map; /** *缓存的实现思路 */ public class CacheDemo { private Map<String, Object> cache=new HashMap<String, Object>(); public static void main(String[] args) { } //同步取数据 public synchronized Object getData(String key){ Object value=cache.get(key); if(value==null){ value="aaaa";//实际是去queryDB() 查询数据库 } return value; } }
缓存的思路
通过锁实现思路
package concurrent; import java.util.HashMap; import java.util.Map; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; /** *缓存系统的实现思路 * */ public class CacheDemo2 { private Map<String, Object> cache=new HashMap<String, Object>(); private ReadWriteLock rwl=new ReentrantReadWriteLock(); public Object getData(String key){ rwl.readLock().lock(); Object value=null; try { value = cache.get(key); if(value==null){ rwl.readLock().unlock();//1 、这里不解读锁, 后面调用写锁直接进入死锁状态。 rwl.writeLock().lock(); try { if(value==null){ value="aaaa";//实际是去
queryDBcache.put(key, value); } } finally {
rwl.readLock.lock(); //2、 在写锁内调用读锁是可以的,叫做降级锁。 rwl.writeLock().unlock(); } } } catch (Exception e) { e.printStackTrace(); }finally{ rwl.readLock().unlock(); } return value; } }