您的位置:首页 > 编程语言 > Java开发

java5读写锁技术的妙用

2018-01-17 00:00 141 查看

一、概述

读写锁:分为读锁和写锁,多个读锁不互斥,读锁与写锁互斥,这是由jvm自己控制的,你只要上好相应的锁即可。如果你的代码只读数据,可以很多人同时读,但不能同时写,那就上读锁;如果你的代码修改数据,只能有一个人在写,且不能同时读取,那就上写锁。总之,读的时候上读锁,写的时候上写锁!

二、代码描述

1、ReadWriteLockTest.java

/**
* @Title: ReadWriteLockTest.java
* @Package com.lh.threadtest.t10
* @Description: TODO
* @author Liu
* @date 2018年1月17日 下午5:17:47
* @version V1.0
*/
package com.lh.threadtest.t10;

import java.util.Random;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
* @ClassName: ReadWriteLockTest
* @Description: TODO
* @author Liu
* @date 2018年1月17日 下午5:17:47
*
*/
public class ReadWriteLockTest {
public static void main(String[] args) {
final Queue3 q3 = new Queue3();
for(int i=0;i<3;i++)
{
new Thread(){
public void run(){
while(true){
q3.get();
}
}

}.start();
}
for(int i=0;i<3;i++)
{
new Thread(){
public void run(){
while(true){
q3.put(new Random().nextInt(10000));
}
}

}.start();
}
}
}

class Queue3{
private Object data = null;//共享数据,只能有一个线程能写该数据,但可以有多个线程同时读该数据。
private ReadWriteLock rwl = new ReentrantReadWriteLock();

public void get(){
rwl.readLock().lock();

try {
System.out.println(Thread.currentThread().getName() + " be ready to read data!");
Thread.sleep((long)(Math.random()*1000));
System.out.println(Thread.currentThread().getName() + "have read data :" + data);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
rwl.readLock().unlock();
}

}

public void put(Object data){
rwl.writeLock().lock();

try {
System.out.println(Thread.currentThread().getName() + " be ready to write data!");
Thread.sleep((long)(Math.random()*1000));
this.data = data;
System.out.println(Thread.currentThread().getName() + " have write data: " + data);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
rwl.writeLock().unlock();
}

}
}


2、CachedDB.java

/**
* @Title: CachedDB.java
* @Package com.lh.threadtest.t10
* @Description: TODO
* @author Liu
* @date 2018年1月17日 下午6:12:33
* @version V1.0
*/
package com.lh.threadtest.t10;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
* @ClassName: CachedDB
* @Description: TODO
* @author Liu
* @date 2018年1月17日 下午6:12:33
*
*/
public class CachedDB {

/***
* @Title: main
* @Description: TODO
* @param @param args
* @return void
* @throws
*/
public static void main(String[] args) {
Business business = new Business();

for(int i = 1; i <= 3; i++){
for(int j = 1; j <= 3; j++){
final int target = j;
new Thread(new Runnable() {

@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " val: " + business.getAndSet(target + ""));
}
},"threadName-" + target).start();
}
}
}
}

class Business{
private static Map<String, Integer> cachedMap = new HashMap<>();

private ReadWriteLock rwl = new ReentrantReadWriteLock();

static{
cachedMap.put("xiaofang", 1);
cachedMap.put("xiaobai", 2);
cachedMap.put("xiaomei", 3);
}

public Integer getAndSet(String name){
rwl.readLock().lock();
Integer target = null;
try {
target = cachedMap.get(name);
if(Objects.isNull(target)){
rwl.readLock().unlock();
rwl.writeLock().lock();
try {
if(Objects.isNull(target)){
target = name.equals("1") ? 10 : (name.equals("2") ? 100 : 1000);//去查询数据库
cachedMap.put(name, target);
}
} finally {
rwl.writeLock().unlock();
}
rwl.readLock().lock();

//use...

}
} finally {
rwl.readLock().unlock();
}
return target;
}
}


三、读写锁API缓存demo



参考资料

1、java中ReentrantReadWriteLock读写锁的使用

2、java并发编程系列之ReadWriteLock读写锁的使用
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  多线程 读写锁