package test;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* 设计一个缓存系统
* 读写锁的应用。
* JDK1.5自带的读写锁特性,读与读不互斥,读与写互斥,写与写互斥。
* 为什么要使用读写锁?一句话概括那就是提高系统性能,如何提高呢?
* 试想,对于所有对读的操作是不需要线程互斥的,而如果方法内
* 使用了synchronized关键字同步以达到线程安全,对于所有的线程不管是读还是写的操作都要同步。
* 这时如果有大量的读操作时就会又性能瓶颈。
*
* 所以,当一个方法内有多个线程访问,并且方法内有读和写读操作时,
* 提升性能最好的线程安全办法时采用读写锁的机制对读写互斥、写写互斥。这样对于读读就没有性能问题了
* @author zhurudong
*
*/
public class CacheTest {
// 缓存的map
private Map<String, Object> map = new HashMap<String, Object>();
// 读写锁对象
private ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
/**
* 从缓存中获取数据的方法
* @param key
* @return
*/
public Object getData(String key) {
readWriteLock.readLock().lock();//读锁,只对写的线程互斥
Object value = null;
try {
// 尝试从缓存中获取数据
value = map.get(key);
if (value == null) {
readWriteLock.readLock().unlock();//发现目标值为null,释放掉读锁
readWriteLock.writeLock().lock();//发现目标值为null,需要取值操作,上写锁
try {
value = map.get(key);// 很严谨这一步。再次取目标值
if (value == null) {//很严谨这一步。再次判断目标值,防止写锁释放后,后面获得写锁的线程再次进行取值操作
// 模拟DB操作
value = new Random().nextInt(10000) + "test";
map.put(key, value);
System.out.println("db completed!");
}
readWriteLock.readLock().lock();//再次对读进行锁住,以防止写的操作,造成数据错乱
} finally {
/*
* 先加读锁再释放写锁读作用:
* 防止在43行出多个线程获得写锁进行写的操作,所以在写锁还没有释放前要上读锁
*/
readWriteLock.writeLock().unlock();
}
}
} finally {
readWriteLock.readLock().unlock();
}
return value;
}
/**
* test main
* @param args
*/
public static void main(String[] args) {
final CacheTest cache = new CacheTest();
final String key = "user";
for (int i = 0; i < 1000; i++) {
new Thread(){
public void run() {
System.out.println(cache.getData(key));
};
}.start();
}
}
}
设计一个缓存系统 java多线程读写锁的应用
原文作者:java锁
原文地址: https://blog.csdn.net/u010959000/article/details/50959994
本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
原文地址: https://blog.csdn.net/u010959000/article/details/50959994
本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。