標籤:system sys 寫鎖 this 共用資料 mod 多線程 java 系統
在多線程中,為了提高效率有些共用資源同意同一時候進行多個讀的操作,但僅僅同意一個寫的操作,比方一個檔案,僅僅要其內容不變能夠讓多個線程同一時候讀,不必做排他的鎖定,排他的鎖定僅僅有在寫的時候須要,以保證別的線程不會看到資料不完整的檔案。這時候就須要使用讀寫鎖。
/** * 簡單讀寫鎖demo * @author hejingyuan * */public class ReadWriteLockTest {public static void main(String[] args) {final Queue3 q3 = new Queue3();//建立幾個線程for(int i=0;i<3;i++){new Thread(){public void run(){while(true){q3.get();}}}.start();new Thread(){public void run(){while(true){q3.put(new Random().nextInt(10000));}}}.start();}}}class Queue3{private Object data = null;//共用資料。僅僅能有一個線程能寫該資料,但能夠有多個線程同一時候讀該資料//讀寫鎖ReadWriteLock rwl = new ReentrantReadWriteLock();//讀資料public void get(){rwl.readLock().lock();try {System.out.println(Thread.currentThread().getName() + " be ready to read data!");Thread.sleep((long)(Math.random()*1000));System.out.println(Thread.currentThread().getName() + "have read data :" + data);} catch (InterruptedException e) {e.printStackTrace();}finally{rwl.readLock().unlock();}}//寫資料public void put(Object data){rwl.writeLock().lock();try {System.out.println(Thread.currentThread().getName() + " be ready to write data!");Thread.sleep((long)(Math.random()*1000));this.data = data;System.out.println(Thread.currentThread().getName() + " have write data: " + data);} catch (InterruptedException e) {e.printStackTrace();}finally{rwl.writeLock().unlock();}}}
運行結果:
Thread-0 be ready to readdata!
Thread-2 be ready to readdata!
Thread-2have read data:null
Thread-0have read data:null
Thread-1 be ready towrite data!
Thread-1 have write data:1021
Thread-1 be ready towrite data!
Thread-1 have write data:2887
看到這裡不免有人會問。既然讀的時候能夠多人訪問。那麼為什麼還要加讀鎖呢?
答:當然要加鎖了,否則在寫時去讀,可能不對-(寫的時候不能去讀)
讀寫鎖-類比緩衝系統實現:
public class CacheDemo {private Map<String, Object> cache = new HashMap<String, Object>();public static void main(String[] args) {}//定義讀寫鎖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;}}
總結:
讀寫鎖的作用為,當我們加上寫鎖時,其它線程被堵塞,僅僅有一個寫操作在運行,當我們加上讀鎖後,它是不會限制多個讀線程去訪問的。也就是get和put之間是相互排斥的。put與不論什麼線程均為相互排斥。可是get與get線程間並非相互排斥的。事實上加讀寫鎖的目的是同一把鎖的讀鎖既能夠與寫鎖相互排斥,讀鎖之間還能夠共用。
JAVA 並發編程-讀寫鎖之類比緩衝系統(十一)