错误案例1:
package com.net.thread.lock;import java.util.HashMap;import java.util.Map;import java.util.concurrent.locks.ReadWriteLock;import java.util.concurrent.locks.ReentrantReadWriteLock;/** * @author * @Time:2017年8月23日 下午6:09:20 * @version 1.0 * @description 读写锁模拟缓存技术 ,错误写法1 */public class Example{ public static void main(String[] args) { Demo demo = new Demo(); new Thread(new Runnable() { @Override public void run() { System.out.println(demo.get("java")); } }).start(); new Thread(new Runnable() { @Override public void run() { System.out.println(demo.get("java")); } }).start(); } static class Demo { ReadWriteLock rwl = new ReentrantReadWriteLock(); Map
错误案例2: 在前一个案例中进行改造,但不完全;此例子中的flag是局部变量,而局部变量实际上是线程安全,就相当于每个线程开始都有一个flag=false的结果,因此,多次调用,多次初始化,并没有起到缓存的作用
package com.net.thread.lock;import java.util.HashMap;import java.util.Map;import java.util.concurrent.locks.ReadWriteLock;import java.util.concurrent.locks.ReentrantReadWriteLock;/** * @author * @Time:2017年8月23日 下午6:09:20 * @version 1.0 * @description 读写锁模拟缓存技术,错误写法2 */public class Example2{ public static void main(String[] args) { Demo demo = new Demo(); new Thread(new Runnable() { @Override public void run() { System.out.println(demo.get("java")); } }).start(); new Thread(new Runnable() { @Override public void run() { System.out.println(demo.get("java")); } }).start(); } static class Demo { ReadWriteLock rwl = new ReentrantReadWriteLock(); Mapmap = new HashMap (); int i = 1; public Object get(Object key) { boolean flag = false; rwl.readLock().lock(); Object value = map.get(key); while (value == null) { System.out.println(Thread.currentThread().getName() + " 的flag:" + flag); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } rwl.readLock().unlock(); rwl.writeLock().lock(); if (!flag) { map.put(key, "初始化"); flag = true; System.out.println(Thread.currentThread().getName() + "写完后的flag :" + flag + " 次数:" + i); i++; } rwl.writeLock().unlock(); rwl.readLock().lock(); value = map.get(key); } rwl.readLock().unlock(); return value; } }}
正确写法:
package com.net.thread.lock;import java.util.HashMap;import java.util.Map;import java.util.concurrent.locks.ReadWriteLock;import java.util.concurrent.locks.ReentrantReadWriteLock;/** * @author * @Time:2017年8月23日 下午6:09:20 * @version 1.0 * @description 读写锁模拟缓存技术,正确写法 */public class Example3{ public static void main(String[] args) { Demo demo = new Demo(); new Thread(new Runnable() { @Override public void run() { System.out.println(demo.get("java")); } }).start(); new Thread(new Runnable() { @Override public void run() { System.out.println(demo.get("java")); } }).start(); } static class Demo { ReadWriteLock rwl = new ReentrantReadWriteLock(); Mapmap = new HashMap (); int i = 1; boolean flag = false; public Object get(Object key) { rwl.readLock().lock(); Object value = map.get(key); while (value == null) { System.out.println(Thread.currentThread().getName() + " 的flag:" + flag); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } rwl.readLock().unlock(); rwl.writeLock().lock(); if (!flag) { map.put(key, "初始化"); flag = true; System.out.println(Thread.currentThread().getName() + "写完后的flag :" + flag + " 次数:" + i); i++; } rwl.writeLock().unlock(); rwl.readLock().lock(); value = map.get(key); } rwl.readLock().unlock(); return value; } }}