做笔记是个好习惯,简单的东西有时候还真管用
一、ReentrantReadWriteLock分别使用
readLock();
writeLock();
来实现数据的读写操作。
public static void main(String[] args) {
//读写案例
fored();
//模拟缓存数据
Object value = CacheTest.get("key");
System.out.println(value);
}
public static void fored(){
final Queued queued = new Queued();
for(int i=0;i<5;i++){
new Thread(){
public void run(){
while(true){
queued.read();
}
}
}.start();
}
for(int i=0;i<5;i++) {
new Thread(){
public void run(){
while(true){
queued.write(new Random().nextInt(1000));
}
}
}.start();
}
}
二、模拟读写
class Queued{
private static Object data = null;//共享数据,只能有一个线程能写该数据,但可以有多个线程同时读该数据。
private static ReadWriteLock rwl = new ReentrantReadWriteLock();
public static void read(){
rwl.readLock().lock();//上读锁,其他线程只能读不能写
System.out.println(Thread.currentThread().getName()+" begin read data");
try {
Thread.sleep((long)(Math.random()*1000));
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
System.out.println(Thread.currentThread().getName()+" end read data :" + data);
rwl.readLock().unlock(); //释放读锁,最好放在finnaly里面
}
}
public void write(Object data){
rwl.writeLock().lock();//上写锁,不允许其他线程
try {
Thread.sleep((long)(Math.random()*1000));
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
this.data = data;
System.out.println(Thread.currentThread().getName()+" end write data:" + data);
rwl.writeLock().unlock();//释放写锁
}
}
}
三、使用读写锁模拟一个缓存器
class CacheTest {
private static Map<String, Object> map = new HashMap<String, Object>();//缓存数据
private static ReadWriteLock rwl = new ReentrantReadWriteLock();
public static Object get(String key){
Object value = null;
rwl.readLock().lock();//首先开启读锁,从缓存中去取
try{
value = map.get(key);
if(value == null){ //如果缓存中没有释放读锁,上写锁
rwl.readLock().unlock();
rwl.writeLock().lock();
try{
if(value == null){
map.put("key", "value"); //此时可以去数据库中查找,这里简单的模拟一下
}
}finally{
rwl.writeLock().unlock(); //释放写锁
}
rwl.readLock().lock(); //然后再上读锁
}
}finally{
rwl.readLock().unlock(); //最后释放读锁
}
return map.get(key);
}
}
四、案例结合了网上的一些建议,但是感觉性能不高,不知是否有更好的?希望各位提点改进意见或者其他的demo