package com.thread.demo.lock; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; /** * * @author Torey * */ public class CacheDemo { // 創建一個緩存對象 static Map<String, Object> cache = Collections .synchronizedMap(new HashMap<>()); static ReadWriteLock rwLock = new ReentrantReadWriteLock(); /** * 定義一個獲取數據的方法 * * @param key * @return */ public Object getData(String key) { // 開啟讀鎖 rwLock.readLock().lock(); Object value = null; try { // 獲取到緩沖對象中的數據 value = cache.get(key); if (value == null) { // 關閉讀鎖 rwLock.readLock().unlock(); // 開啟 寫鎖 rwLock.writeLock().lock(); try { value = cache.get(key); if (value == null) { System.out.println("從DB獲取數據:" + key); cache.put(key, key + "_key的值"); value = cache.get(key); } else { System.out.println("從緩存讀取:"); value = cache.get(key); } } catch (Exception ex) { ex.printStackTrace(); } finally { // 釋放寫鎖 rwLock.writeLock().unlock(); } // 釋放讀鎖 rwLock.readLock().lock(); } else { System.out.println("從緩存讀取"); value = cache.get(key); } } catch (Exception ex) { ex.printStackTrace(); } finally { // 關閉讀鎖 rwLock.readLock().unlock(); } return value; } static class CacheRunnable implements Runnable { @Override public void run() { // TODO Auto-generated method stub for (int i = 0; i < 3; i++) { System.out.println(Thread.currentThread().getName() + "_" + i+"="+new CacheDemo().getData(Thread.currentThread().getName() + "_" + i)); } } } public static void main(String[] args) { for (int i = 0; i < 3; i++) { new Thread(new CacheRunnable(), "線程").start(); } } }