java5读写锁技术的妙用

一、概述

      读写锁:分为读锁和写锁,多个读锁不互斥,读锁与写锁互斥,这是由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

100230_oYb1_3144678.png

参考资料

1、java中ReentrantReadWriteLock读写锁的使用

2、java并发编程系列之ReadWriteLock读写锁的使用

转载于:https://my.oschina.net/Howard2016/blog/1608769

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值