多线程之ReadWriteLock模拟缓存(九)
错误案例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;
}
}
}
多线程之ReadWriteLock模拟缓存(九)的更多相关文章
- Java多线程之ReadWriteLock读写锁简介与使用教程
转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6558073.html 普通的锁在对某一内容加锁后,其他线程是不能访问的.但是我们要考虑这种情况:如果当前加锁 ...
- WebAPI调用笔记 ASP.NET CORE 学习之自定义异常处理 MySQL数据库查询优化建议 .NET操作XML文件之泛型集合的序列化与反序列化 Asp.Net Core 轻松学-多线程之Task快速上手 Asp.Net Core 轻松学-多线程之Task(补充)
WebAPI调用笔记 前言 即时通信项目中初次调用OA接口遇到了一些问题,因为本人从业后几乎一直做CS端项目,一个简单的WebAPI调用居然浪费了不少时间,特此记录. 接口描述 首先说明一下,基于 ...
- Java基础-进程与线程之Thread类详解
Java基础-进程与线程之Thread类详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.进程与线程的区别 简而言之:一个程序运行后至少有一个进程,一个进程中可以包含多个线程 ...
- JAVA 并发编程-读写锁之模拟缓存系统(十一)
在多线程中,为了提高效率有些共享资源同意同一时候进行多个读的操作,但仅仅同意一个写的操作,比方一个文件,仅仅要其内容不变能够让多个线程同一时候读,不必做排他的锁定,排他的锁定仅仅有在写的时候须要,以保 ...
- Java多线程之Runnable与Thread
Java多线程之Thread与Runnable 一.Thread VS Runnable 在java中可有两种方式实现多线程,一种是继承Thread类,一种是实现Runnable接口:Thread类和 ...
- 多线程之Lock接口
之前写了一下synchronized关键字的一点东西,那么除了synchronized可以加锁外,JUC(java.util.concurrent)提供的Lock接口也可以实现加锁解锁的功能. 看完本 ...
- iOS多线程之8.NSOPeration的其他用法
本文主要对NSOPeration的一些重点属性和方法做出介绍,以便大家可以更好的使用NSOPeration. 1.添加依赖 - (void)addDependency:(NSOperation * ...
- python 线程之 threading(四)
python 线程之 threading(三) http://www.cnblogs.com/someoneHan/p/6213100.html中对Event做了简单的介绍. 但是如果线程打算一遍一遍 ...
- python 线程之 threading(三)
python 线程之 threading(一)http://www.cnblogs.com/someoneHan/p/6204640.html python 线程之 threading(二)http: ...
随机推荐
- [Cuckoo SandBox]注入原理篇
1.LoadExe 接python版本 通过调用LoadExe去加载Dll进行注入 所以先看LoadExe 加载器的功能吧 通过python管道接收到 processID,ThreadID,路径 , ...
- Python基本操作之文件操作
一. 1.文件操作的函数 open("文件名字(路径)",mode="模式",encoding="字符集") 2.模式:r,w,a,r+,w ...
- Struts2_带参数的结果集
页面请求: <a href="user/user?type=1">传参数</a> action: public Integer type; public S ...
- Java—继承
继承 继承是类与类的一种关系,是一种“is a”的关系.注意:java中的继承是单继承,一个类只有一个父类. 继承的好处:子类拥有父类的所有属性和方法(private修饰的无效),实现代码的复用 语法 ...
- C#设计模式--工厂模式(创建型模式)
一.简单工厂模式(UML类图): 核心类代码: public class Calc { public double NumberA { get; set; } public double Number ...
- 开源时序服务器influxdb使用
文档 https://influxdb.com/docs/v0.9/introduction/overview.html 配置文件 /etc/opt/influxdb/influxdb.conf re ...
- Active Directory域服务备份
此篇介绍如何通过Windows Server Backup工具备份Active Directory域服务 AD 域系统状态 在域控制器上,系统状态通常包括以下内容,但所包含的数据实际上取决于服务器上安 ...
- 【Troubleshooting 】Outlook 客户端无法显示电子邮件图像
出于安全原因,Outlook 2013/2016不会在电子邮件中显示图像,但您可以右键单击图像并选择" 下载图片 "选项.我最近注意Outlook停止显示图像,并且没有下载图像的选 ...
- Python基础学习之变量赋值
1.赋值操作符 Python语言中,等号(=)是主要的赋值操作符: >>> aInt=-100 >>> aString='this is a string' > ...
- Jmeter入门5 关联 响应数据传递-正则表达式提取器
在测试过程中,遇到一个问题:用户登录成功后服务器会返回一个登录凭证,之后所有的操作都需要带上此凭证.我们怎么获取登录凭证并传递给后续的操作? Jmeter提供了正则表达式提取器,用变量提取参数,后续通 ...