您好,登錄后才能下訂單哦!
本篇文章給大家分享的是有關關于讀寫鎖算法的Java實現及思考是怎么樣的,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。
問題背景:多個線程對一個共享的資源進行讀寫訪問。寫線程之間需要互斥,讀線程跟寫線程需要互斥,讀線程之間不用互斥。
早些時候聽張sir的課,講述java5中增強并發的功能。用java.util.concurrent.locks中ReadWriteLock 可以輕松解決讀寫鎖問題。我在思考如果沒有ReadWriteLock,單靠synchronized可以怎樣做呢? 的確,比較麻煩。
1.結合張sir傳授的面向對象的設計思想,首先設計一個業務類Business作為共享資源,封裝write跟read方法。
2.因為write必定互斥,所以直接定義synchronized。
3.read之間不要互斥 所以read 不能直接定義synchronized的 但是 write跟read 需要互斥 如何控制 我想到的一個方法是在read里 加入synchronized(this){} 同時定義readThreads計數器作為信號量 我試想下會出現下面幾種情況:
read[m]表示某個線程的read方法 。
write[n] 同上
1>read[m]中執行到synchronized(this){readThreads++;}時 write[n]來了 write[n] 會被自身的synchronized阻塞。
2>read[m]在do something(此時無鎖)時 write[n] 來了 因為 readThreads!=0 而被迫wait。
3> 每次read[m]結束時 wait中的write[n]會被notify 但如果發現還有其他的read的話 write[n] 只能無奈地再次wait。
4>當readThreads==0并且調用notifyAll 時 read[m] 和 write[n] 會競爭cpu 如果write[n]再次落敗,則會出現1>或3> ; 如果成了,則如下:
5> 如果write[n] wait中醒來占鎖,read[m]被阻塞synchronized(this){readThreads++;}之上。
6>如果被阻塞的write[n]占鎖,read[m]被阻塞synchronized(this){readThreads++;}之上。
從以上看來read 和 write 是互斥的。
4.實現細節如下:<如有錯誤歡迎指出交流>
package communication; import java.util.Random; public class ReadWriteLockTest { public static void main(String[] args){ final Business business = new Business(); //啟動4線程 2讀 2寫 for(int i=1;i<=2;i++){ new Thread(new Runnable(){ public void run() { for(int j=1;j<1000;j++){ business.read(); try { Thread.sleep(900); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); new Thread(new Runnable(){ public void run() { Random r = new Random(); for(int j=1;j<1000;j++){ int i = r.nextInt(100); business.write(i); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); } } } //封裝的業務類 class Business{ private int data=0; //共享資源屬性 private int readThreads = 0; //讀線程數 //private boolean isWriting = false; //是否執行寫 后來發現不需要 當write搶占鎖時 所有的read 都被擋在synchronized (this){}之上 無機會執行wait public void read(){ synchronized (this) { /*while(isWriting){ try { this.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } }*/ //readThreads不被鎖的話 會出現read和write不互斥的小概率事件 導致線程不安全 readThreads++; } System.out.println(Thread.currentThread().getName()+" read begin"); System.out.println(Thread.currentThread().getName()+" read:"+data); System.out.println(Thread.currentThread().getName()+" read finish"); synchronized (this) { readThreads--; this.notifyAll(); } } public synchronized void write(int i){ while(readThreads != 0){//當read 正處于do something狀態時 來個write 那就只有等等先了 try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } //isWriting = true; System.out.println(Thread.currentThread().getName()+" write start"); data = i; System.out.println(Thread.currentThread().getName()+" write:"+i); System.out.println(Thread.currentThread().getName()+" write over"); //isWriting = false; this.notifyAll(); } }
思考中:
5.當讀頻繁時 readThreads會長時間!= 0 寫線程會餓死 這個可以如何解決?
以上就是關于讀寫鎖算法的Java實現及思考是怎么樣的,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。