多线程之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: ...
随机推荐
- Java类的初始化顺序 (静态变量、静态初始化块、变量、初始...
很有意思的一篇文章 1.没有继承 静态变量->静态初始化块->变量->变量初始化块->构造方法 2.有继承的情况 父类静态变量->父类静态初始化块->子类静态变量- ...
- jQuery设置全选和全反选
HTML 代码: <input type="checkbox" id="allChecked" onclick="setAllChecked(t ...
- 在页面rem布局中用到的js代码
在你的页面加入以下代码,就初步搞定了 function fontSize() { var view_width = document.getElementsByTagName('html')[0].g ...
- (四)JavaScript之[break和continue]与[typeof、null、undefined]
7].break和continue /** * JavaScript 的break和continue语句 * break 跳出switch()语句 * break 用于跳出循环 * continue ...
- C++ Knowledge series Conversion & Constructor & Destructor
Everything has its lifecycle, from being created to disappearing. Pass by reference instead of pass ...
- centreon-engine 性能调优
http://documentation.centreon.com/docs/centreon-engine/en/latest/user/configuration/best_practice.ht ...
- Ubuntu 如何将桌面上的Home中的文件夹除去
安装Ubuntu后, 由于无法用Terminal(终端)进入带中文的文件夹,会引起很多操作不便.很多朋友想到了将它们都改成中文,但是当再次开机重启使却会发现,原本光洁的桌面现在竟然出现了一堆文件夹?? ...
- 修改hosts工具推荐SwitchHosts
推荐一个修改hosts的工具.适合平时工作中经常修改hosts的开发测试. 下载地址:https://oldj.github.io/SwitchHosts/ 可以按各种环境或者项目添加,用的时候打开或 ...
- Graylog安装操作
Graylog安装操作 实验环境centos7.5系统 mem:4-8G disk:50G 关闭selinux以及firewalld 一.准备环境 1.1.java环境 下载java的j ...
- 转:SSM框架——详细整合教程(Spring+SpringMVC+MyBatis)
转:https://www.cnblogs.com/zyw-205520/p/4771253.html 1.基本概念 1.1.Spring Spring是一个开源框架,Spring是于2003 年 ...