错误案例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. poj 3140 树形去边差异最小

    http://poj.org/problem?id=3140 依然是差异最小问题,不过这次是去边.思路是这样的,先记录每个点的子节点个数,然后遍历每个边. 有两个问题要注意: abs可能会出编译适配问 ...

  2. #include stdio.h(4)

    #include <stdio.h> int main() { //****************1.数组*************** //什么是数组:专门用来存放数据的 /* 格式 ...

  3. 快速配置$XX_TOP方法

    查找配置文件名 执行:env | grep CONTEXT 得到: CONTEXT_FILE=/dev01/oracle/UAT/inst/apps/UAT_ksebsdt/appl/admin/UA ...

  4. 使用 Notapad++ 进行 Java 开发

    准备工具 1.安装 JDK 以及配置相关环境变量: 2.安装 64 位版的 Notepad++ : 2.一台 64 位 Windows 系统电脑: 一.下载&安装Notepad++ 官网下载地 ...

  5. git 获取领先落后的命令

    git --git-dir=/data/usr/local/gerrit-site/git/aixuexi-admin.git rev-list --left-right --count master ...

  6. UDoc(云平台企业应用级 文档管理产品)

    类型: 定制服务 软件包: integrated industry solution collateral 联系服务商 产品详情 解决方案 概要 为企业提供基于云平台企业应用级文档管理产品,尽可能最大 ...

  7. Limesurvey-2.55 (Ubuntu 16.04)

    平台: Ubuntu 类型: 虚拟机镜像 软件包: limesurvey-2.55 business intelligence commercial limesurvey open-source 服务 ...

  8. COGS 146. [USACO Jan08] 贝茜的晨练计划

    ★☆   输入文件:cowrun.in   输出文件:cowrun.out   简单对比时间限制:1 s   内存限制:32 MB 奶牛们打算通过锻炼来培养自己的运动细胞,作为其中的一员,贝茜选择的运 ...

  9. April 21 2017 Week 16 Friday

    Courage is like a muscle. We strengthen it with use. 勇气就像肌肉,越使用越强大. Most often it is true, but somet ...

  10. Poj(1521),哈夫曼编码

    题目链接:http://poj.org/problem?id=1521 这里,网上有很多博客都有写,很多人没有建树,直接就是求一下这个哈夫曼编码的长度,的确很巧妙,我也用的这个方法,但是,几乎所有博客 ...