package locks;

import java.util.Random;
import java.util.concurrent.locks.ReentrantReadWriteLock; /*
*ReentrantReadWriteLock 读写互斥,
*如果读操作被上锁,写操作就不能进行,
*如果写操作被上锁,读操作就不能进行,
*
*读操作上锁后,需要解锁后, 写才能上锁。
* 如果读没有解锁,还调用了写的锁,就会造成堵塞,让线程卡在哪里。
* 反之却是可以的,即在写没有解锁,读操作上锁是可以的。(叫做降级锁)
*
*/
public class ReadWriteLockTest { public static void main(String[] args) {
final Queue q3 = new Queue();
// 弄3个读的线程, 弄3个写的线程
for (int i = 1; i <= 3; i++) {
new Thread() {
public void run() {
while (true) {
q3.put(new Random().nextInt(10000));
}
}
}.start(); new Thread() {
public void run() {
while (true) {
q3.get();
}
}
}.start();
}
}
} class Queue {
private Object data = null;
// hibernate load的方法实现就是 ReentrantReadWriteLock 放在代理对象中
private ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); public void get() {
rwl.readLock().lock();
try {
System.out.println(Thread.currentThread().getName() + "开始取");
Thread.sleep((long) (Math.random() * 1000));
System.out.println(Thread.currentThread().getName() + "取完毕" + data);
} catch (InterruptedException e) {
e.printStackTrace();
}
rwl.readLock().unlock();
} public void put(Object obj) {
rwl.writeLock().lock();
try {
System.out.println(Thread.currentThread().getName() + "开始写");
Thread.sleep((long) (Math.random() * 1000));
this.data = obj;
System.out.println(Thread.currentThread().getName() + "写结束" + obj); } catch (InterruptedException e) {
e.printStackTrace();
}
rwl.writeLock().unlock();
}
}

执行结果:

Thread-1开始取
Thread-1取完毕null
Thread-0开始写
Thread-0写结束4973
Thread-4开始写
Thread-4写结束2476
Thread-3开始取
Thread-3取完毕2476
Thread-2开始写
Thread-2写结束3388
Thread-2开始写
Thread-2写结束2905
Thread-5开始取
Thread-1开始取
Thread-1取完毕2905
Thread-5取完毕2905
Thread-0开始写
Thread-0写结束4504
Thread-4开始写
Thread-4写结束9962
Thread-3开始取
Thread-3取完毕9962
Thread-2开始写
Thread-2写结束3281
Thread-2开始写
Thread-2写结束1530
Thread-1开始取
Thread-5开始取
Thread-5取完毕1530
Thread-1取完毕1530
Thread-0开始写
Thread-0写结束8294
Thread-0开始写
Thread-0写结束7573
Thread-4开始写
Thread-4写结束4506
Thread-4开始写
Thread-4写结束4768
Thread-3开始取
Thread-3取完毕4768
Thread-2开始写

package concurrent;

import java.util.HashMap;
import java.util.Map;
/**
*缓存的实现思路
*/
public class CacheDemo { private Map<String, Object> cache=new HashMap<String, Object>();
public static void main(String[] args) { } //同步取数据
public synchronized Object getData(String key){
Object value=cache.get(key); if(value==null){
value="aaaa";//实际是去queryDB() 查询数据库
}
return value;
}
}

缓存的思路

通过锁实现思路

package concurrent;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
*缓存系统的实现思路
*
*/
public class CacheDemo2 { private Map<String, Object> cache=new HashMap<String, Object>();
private ReadWriteLock rwl=new ReentrantReadWriteLock();
public Object getData(String key){ rwl.readLock().lock();
Object value=null;
try {
value = cache.get(key);
if(value==null){
rwl.readLock().unlock();//1 、这里不解读锁, 后面调用写锁直接进入死锁状态。
rwl.writeLock().lock();
try {
if(value==null){
value="aaaa";//实际是去
              queryDBcache.put(key, value);
}
} finally {
            rwl.readLock.lock(); //2、 在写锁内调用读锁是可以的,叫做降级锁。
rwl.writeLock().unlock();
} }
} catch (Exception e) {
e.printStackTrace();
}finally{
rwl.readLock().unlock();
}
return value;
}
}

多线程12_张孝祥 java5读写锁技术的妙用的更多相关文章

  1. Lock读写锁技术的妙用

    1.面试题1:三个线程读,三个线程写同一个数据 public class ReadWriteLockTest { public static void main(String[] args) { fi ...

  2. 22、Java并发性和多线程-Java中的读/写锁

    以下内容转自http://ifeve.com/read-write-locks/: 相比Java中的锁(Locks in Java)里Lock实现,读写锁更复杂一些.假设你的程序中涉及到对一些共享资源 ...

  3. Linux多线程实践(6) --Posix读写锁解决读者写者问题

    Posix读写锁 int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *rest ...

  4. 多线程11_张孝祥 java5的线程锁技术

    本例子因为两个线程公用同线程中,使用同一个对象,实现了他们公用一把锁,实现了同一个方法的互斥. package locks; /** *会被打乱的效果 */ public class LockTest ...

  5. 用读写锁三句代码解决多线程并发写入文件 z

    C#使用读写锁三句代码简单解决多线程并发写入文件时提示“文件正在由另一进程使用,因此该进程无法访问此文件”的问题 在开发程序的过程中,难免少不了写入错误日志这个关键功能.实现这个功能,可以选择使用第三 ...

  6. C#使用读写锁三行代码简单解决多线程并发写入文件时线程同步的问题

    (补充:初始化FileStream时使用包含文件共享属性(System.IO.FileShare)的构造函数比使用自定义线程锁更为安全和高效,更多内容可点击参阅) 在开发程序的过程中,难免少不了写入错 ...

  7. C# 防止同时调用=========使用读写锁三行代码简单解决多线程并发的问题

    http://www.jb51.net/article/99718.htm     本文主要介绍了C#使用读写锁三行代码简单解决多线程并发写入文件时提示"文件正在由另一进程使用,因此该进程无 ...

  8. 技术笔记:Delphi多线程应用读写锁

    在多线程应用中锁是一个很简单又很复杂的技术,之所以要用到锁是因为在多进程/线程环境下,一段代码可能会被同时访问到,如果这段代码涉及到了共享资源(数据)就需要保证数据的正确性.也就是所谓的线程安全.之前 ...

  9. java多线程-读写锁原理

    Java5 在 java.util.concurrent 包中已经包含了读写锁.尽管如此,我们还是应该了解其实现背后的原理. 读/写锁的 Java 实现(Read / Write Lock Java ...

随机推荐

  1. MHA自动切换流程

    MHA的全名叫做mysql-master-ha,配置后可以在10-30秒内完成master自动切换,切换过程如下: 1. 检测master的状态,方法是一秒一次“ SELECT 1 As Value” ...

  2. 2014年2月5日 Oracle ORACLE的工作机制[转]

      网上看到一篇描写ORACLE工作机制的文章,觉得很不错!特摘录了下来.   ORACLE的工作机制-1 (by xyf_tck) 我们从一个用户请求开始讲,ORACLE的简要的工作机制是怎样的,首 ...

  3. IOS开发系列 --- 核心动画

    原始地址:http://www.cnblogs.com/kenshincui/p/3972100.html 概览 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥i ...

  4. Sql Server相关的性能计数器

    OS Memory and Paging 性能计数器: 1.Memory\Availability Mbytes   未使用的物理内存(非页面文件),通常情况下它应该大于100MB 2.Memory\ ...

  5. C++程序设计实践指导1.3求任意整数降序数改写要求实现

    改写要求1:动态生成单链表存储 #include <cstdlib> #include <iostream> using namespace std; struct LinkN ...

  6. oracle数据库管理--用户管理

    一.oracle数据库用户管理 1.sys和system用户区别 (1)存储的数据的重要性不同:        sys所有oracle的数据字典的基表和视图都存放在sys用户中,这些基表和视图对于or ...

  7. avalon前端js直接通过ajax请求传一个对象到后台

    代码如下:                //企业开票信息      vm.invoiceInfo = {       companyId : "",            //企 ...

  8. 已知要闪回的大致时间使用基于as of scn的闪回查询

    基本判断出要恢复误操作的dml的时间可以使用如下的方法进行数据的恢复: example: 一.创建test表 -------create table flashback_asof------ crea ...

  9. Android 开发使用lambda实现< JDK8兼容

    代码精简无疑是每个程序员的目标,简短易读.java 8中的lambda表达式的使用: 4 easy steps Download and install jdk8. Add the following ...

  10. Linux Power(一): kernel/power/earlysuspend.c

    /* kernel/power/earlysuspend.c * * Copyright (C) 2005-2008 Google, Inc. * * This software is license ...