错误案例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模拟缓存(九)的更多相关文章

  1. Java多线程之ReadWriteLock读写锁简介与使用教程

    转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6558073.html  普通的锁在对某一内容加锁后,其他线程是不能访问的.但是我们要考虑这种情况:如果当前加锁 ...

  2. WebAPI调用笔记 ASP.NET CORE 学习之自定义异常处理 MySQL数据库查询优化建议 .NET操作XML文件之泛型集合的序列化与反序列化 Asp.Net Core 轻松学-多线程之Task快速上手 Asp.Net Core 轻松学-多线程之Task(补充)

    WebAPI调用笔记   前言 即时通信项目中初次调用OA接口遇到了一些问题,因为本人从业后几乎一直做CS端项目,一个简单的WebAPI调用居然浪费了不少时间,特此记录. 接口描述 首先说明一下,基于 ...

  3. Java基础-进程与线程之Thread类详解

    Java基础-进程与线程之Thread类详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.进程与线程的区别 简而言之:一个程序运行后至少有一个进程,一个进程中可以包含多个线程 ...

  4. JAVA 并发编程-读写锁之模拟缓存系统(十一)

    在多线程中,为了提高效率有些共享资源同意同一时候进行多个读的操作,但仅仅同意一个写的操作,比方一个文件,仅仅要其内容不变能够让多个线程同一时候读,不必做排他的锁定,排他的锁定仅仅有在写的时候须要,以保 ...

  5. Java多线程之Runnable与Thread

    Java多线程之Thread与Runnable 一.Thread VS Runnable 在java中可有两种方式实现多线程,一种是继承Thread类,一种是实现Runnable接口:Thread类和 ...

  6. 多线程之Lock接口

    之前写了一下synchronized关键字的一点东西,那么除了synchronized可以加锁外,JUC(java.util.concurrent)提供的Lock接口也可以实现加锁解锁的功能. 看完本 ...

  7. iOS多线程之8.NSOPeration的其他用法

      本文主要对NSOPeration的一些重点属性和方法做出介绍,以便大家可以更好的使用NSOPeration. 1.添加依赖 - (void)addDependency:(NSOperation * ...

  8. python 线程之 threading(四)

    python 线程之 threading(三) http://www.cnblogs.com/someoneHan/p/6213100.html中对Event做了简单的介绍. 但是如果线程打算一遍一遍 ...

  9. python 线程之 threading(三)

    python 线程之 threading(一)http://www.cnblogs.com/someoneHan/p/6204640.html python 线程之 threading(二)http: ...

随机推荐

  1. C#图表控件ZedGraph使用

    最近从java转到C#下开发PC端的桌面程序,之前也尝试用java GUI写桌面程序,发现java写桌面程序还是诸多不便变,虽然最后也写出来了,但是决心还是另起平台,有了一定的java基础,来学习C# ...

  2. SpringBoot 使用fastjson

    spring boot默认使用的json解析框架是jackson,替换为fastjson有两种方式 1.继承WebMvcConfigurerAdapter @SpringBootApplication ...

  3. 拿到返回值,Callable示例

  4. spring 类注入失败,解决之道

    1.今天偶尔发现的问题,如果你在一个类上面用了注解@Async,spring的异步注解之后,发现如果别的类用@Autowired导入这个类时会失败! 解决办法:用了@Async无非是想方便的用异步操作 ...

  5. 在UITableView中识别左右滑动,实现上下翻页的功能

    目前有三种方案: 1. UIScrollView + UITableView. 实现方法,在UIScrollView中,加入UITableView即可 设置UIScrollView的代理和方法 - ( ...

  6. React API

    组件 API setState 合并 nextState 和当前 state. 这是在事件处理函数中和请求回调函数中触发 UI 更新的主要方法. 另外,也支持可选的回调函数,该函数在 setState ...

  7. 开发中常用的sql语句二

    sql 数字全角半角转换 create FUNCTION dbo.ConvertWordAngle ( ), --要转换的字符串 @flag bit --转换标志,0转换成半角,1转换成全角 )) A ...

  8. Odoo (OpenERP/TinyERP)-10.0 (Debian 8)

    平台: Ubuntu 类型: 虚拟机镜像 软件包: odoo-10.0 commercial erp odoo open source openerp tinyerp 服务优惠价: 按服务商许可协议 ...

  9. Oracle数据库基本语句练习

    以ORACLE数据库为主提纲:第一部分.SQL语言基础 第一章:Oracle命令类别及sql简单语法介绍第二章:oracle的基本函数第三章:oracle的数据类型第四章:多表连接技术 第二部分.or ...

  10. PDO链式操作——针对关键字出现问题的解决方案

    例如: 1.执行一条SQL语句:查询user表中的所有数据,并通过name字段进行降序,通过age进行升序 2. 案例1:   正确的执行语句为:SELECT * FROM user ORDER BY ...