首页 > 技术文章 > 多线程12_张孝祥 java5读写锁技术的妙用

laj12347 2015-04-08 21:45 原文

 

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; } }

 

推荐阅读