標籤:code http get alt 多個 dwr 分享 sleep image
相比Java中的鎖(Locks in Java)裡Lock實現,讀寫鎖更複雜一些。假設你的程式中涉及到對一些共用資源的讀和寫操作,且寫操作沒有讀操作那麼頻繁。在沒有寫操作的時候,兩個線程同時讀一個資源沒有任何問題,所以應該允許多個線程能在同時讀取共用資源。但是如果有一個線程想去寫這些共用資源,就不應該再有其它線程對該資源進行讀或寫(譯者註:也就是說:讀-讀能共存,讀-寫不能共存,寫-寫不能共存)。這就需要一個讀/寫鎖來解決這個問題。Java5在java.util.concurrent包中已經包含了讀寫鎖。儘管如此,我們還是應該瞭解其實現背後的原理。
讀 寫 這種的 可以用wait notify 之前已經實現過了 讀的時候不能寫 寫的時候不能做 保證共性的全域變數安全
下面,先來寫個讀寫鎖大家看看:
package com.toov5.readAndWriteLock;import java.util.HashMap;import java.util.Map;//讀寫鎖 類似jvm內建緩衝(把值存到jvm中)public class writeAndReadLock { private volatile Map<Object,Object> cache = new HashMap<>(); //寫入元素 public void put(String key,String value){ try { Thread.sleep(500); System.out.println("寫入"+key+value); cache.put(key, value); System.out.println("寫入"+key+value+"結束"); } catch (InterruptedException e) { e.printStackTrace(); } } //讀取元素 public String get(String key){ try { Thread.sleep(500); System.out.println("讀取"+key); String result = cache.get(key).toString(); System.out.println("讀取"+key+"結束"); return result; } catch (Exception e) { return null; } } public static void main(String[] args) { writeAndReadLock lock = new writeAndReadLock(); //寫線程 Thread t1 = new Thread(new Runnable() { @Override public void run() { for(int i =0; i<10;i++){ lock.put("i", i+""); } } }); //讀線程 Thread t2 = new Thread(new Runnable() { @Override public void run() { for(int i=0; i<10;i++){ lock.get(i+""); } } }); t1.start(); t2.start(); } }
結果:
如果兩個方法都加上synchronize 那麼讀的時候 不能寫 寫的時候不能讀
下面提供讀寫鎖:
package com.toov5.readAndWriteLock;import java.util.HashMap;import java.util.Map;import java.util.concurrent.locks.ReentrantReadWriteLock;import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;//讀寫鎖 類似jvm內建緩衝(把值存到jvm中)public class writeAndReadLock { private volatile Map<Object,Object> cache = new HashMap<>(); private ReentrantReadWriteLock wrl = new ReentrantReadWriteLock(); private WriteLock wirtelock=wrl.writeLock();//擷取到寫鎖 private ReadLock readLock =wrl.readLock(); //擷取到讀鎖 //寫入元素 public void put(String key,String value){ try { wirtelock.lock(); Thread.sleep(500); System.out.println("寫入"+key+value); cache.put(key, value); System.out.println("寫入"+key+value+"結束"); } catch (InterruptedException e) { e.printStackTrace(); }finally { wirtelock.unlock(); } } //讀取元素 public String get(String key){ try { readLock.lock(); Thread.sleep(500); System.out.println("讀取"+key); String result = cache.get(key).toString(); System.out.println("讀取"+key+"結束"); return result; } catch (Exception e) { return null; }finally{ readLock.unlock(); } } public static void main(String[] args) { writeAndReadLock lock = new writeAndReadLock(); //寫線程 Thread t1 = new Thread(new Runnable() { @Override public void run() { for(int i =0; i<10;i++){ lock.put("i", i+""); } } }); //讀線程 Thread t2 = new Thread(new Runnable() { @Override public void run() { for(int i=0; i<10;i++){ lock.get(i+""); } } }); t1.start(); t2.start(); } }
沒有寫完時候 是不能讀的
看源碼:
與之前的lock鎖不一樣之前是 reentrantlock,它有讀和寫兩把鎖
兩個線程同時寫,同時讀是不可能的。不共存!
讀讀 可以 讀寫不可共存 寫寫不可以共存
讀寫鎖