多线程12_张孝祥 java5读写锁技术的妙用

时间:2023-03-09 19:43:58
多线程12_张孝祥  java5读写锁技术的妙用
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;
}
}