讀寫鎖

package com.zhl.practice;

import java.util.Random;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * @author Holley
 * @Description 讀寫鎖(可重入鎖Lock,一個讀鎖能夠有多個線程同時獲取,同一寫鎖同一時間只能有一個線程獲取,寫鎖能夠降級爲讀鎖(在釋放該寫鎖以前獲取讀鎖,而後釋放寫鎖,稱爲鎖降級))
 * @create 2019-05-27 14:54
 **/
public class ReadAndWriteLock {

    // 共享變量
    private Object data = null;

    private ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
    // 讀取共享變量內容(加上鎖以後在一個線程讀取數據完成以前無論中間停頓多久其餘讀取線程均可以插入進來)
    public void getValue(){
        reentrantReadWriteLock.readLock().lock();
        System.out.println(Thread.currentThread().getName() + ":準備讀取數據");
        try {
            Thread.sleep(new Random().nextInt(100)*10);
            System.out.println(Thread.currentThread().getName() + ":讀取數據" + data);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            reentrantReadWriteLock.readLock().unlock();
        }
    }

    // 修改共享變量內容(加上鎖以後在一個線程寫入數據完成以前無論中間停頓多久都沒有其餘線程會插入進來)
    public void put(Object value){
        reentrantReadWriteLock.writeLock().lock();
        System.out.println(Thread.currentThread().getName() + ":準備修改數據");
        try {
            Thread.sleep(new Random().nextInt(1000)*10);
            data = value;
            System.out.println(Thread.currentThread().getName() + ":修改數據爲:" + data);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            reentrantReadWriteLock.writeLock().unlock();
        }
    }

    public static void main(String[] args){
        final ReadAndWriteLock rwl = new ReadAndWriteLock();
        // 建立多個線程讀取數據
        for(int i = 0;i < 5;i++){
            new Thread(() -> {
                while(true){
                    rwl.getValue();
                }
            }).start();
        }
        // 建立多個線程修改數據
        for(int i = 0;i < 5;i++){
            new Thread(() -> {
//                while(true){
                    rwl.put(new Random().nextInt(100));
//                }
            }).start();
        }
    }
}

 

緩存的demo(hibernate中get和load的區別:load是懶加載,若是查詢數據爲空時,get方法返回null,而load方法拋出異常)java

public class CacheDemo {

    private Map<String, Object> cache = new HashMap<String, Object>();
    public static void main(String[] args) {
        // TODO Auto-generated method stub

    }

    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();
                rwl.writeLock().lock();
                try{
                    if(value==null){
                        value = "aaaa";//實際失去queryDB();
                    }
                }finally{
                    rwl.writeLock().unlock();
                }
                rwl.readLock().lock();
            }
        }finally{
            rwl.readLock().unlock();
        }
        return value;
    }
}
相關文章
相關標籤/搜索