多线程之ReadWriteLock模拟缓存(九)
2024-09-07 18:24:09
错误案例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<Object, Object> map = new HashMap<Object, Object>();
boolean flag; public Object get(Object key)
{
rwl.readLock().lock(); Object value = null;
value = map.get(key); //if不安全,如果在这里边的value依旧是null,则根本没有安全保障
if (value == null) {
flag = false;
rwl.readLock().unlock();
rwl.writeLock().lock();
System.out.println(Thread.currentThread().getName() + " 的flag:" + flag);
if (!flag) {
value = null;
map.put(key, value);
flag = true;
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
rwl.writeLock().unlock();
rwl.readLock().lock();
} rwl.readLock().unlock();
return value;
}
} }
错误案例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();
Map<Object, Object> map = new HashMap<Object, Object>();
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();
Map<Object, Object> map = new HashMap<Object, Object>();
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;
}
}
}
最新文章
- linux启动过程分析
- Wireshark抓包分析/TCP/Http/Https及代理IP的识别
- CSS笔记(十四)CSS3之动画
- play framework (一)
- 2013 Multi-University Training Contest 5 Partition
- C# Hashtable中存入数组、List
- 工厂模式(Factory Method)
- BZOJ 1951: [Sdoi2010]古代猪文 [Lucas定理 中国剩余定理]
- 【BZOJ3233】【tyvj1729】文艺平衡树
- hdfs directory item limit - (dfs.namenode.fs-limits.max-directory-items)
- C#利用Guid实现真随机数
- MySQL server has gone away 的两个最常见的可能性
- shell批量修改mysql用户密码
- php基本类型
- 个人前端学习路线图与github优秀前端开发者的路线图推荐
- django项目一 分页器(前端分页和后端分页区别)
- HashMap原理<;转>;
- Linux中的叹号命令
- HTML5API(5)
- hadoop中的方法的作用