java怎么写算法_关于读写锁算法的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.實現細節如下:
packagecommunication;
importjava.util.Random;
publicclassReadWriteLockTest?{
publicstaticvoidmain(String[]?args){
finalBusiness?business?=newBusiness();
//啟動4線程?2讀?2寫
for(inti=1;i<=2;i++){
newThread(newRunnable(){
publicvoidrun()?{
for(intj=1;j<1000;j++){
business.read();
try{
Thread.sleep(900);
}catch(InterruptedException?e)?{
e.printStackTrace();
}
}
}
}).start();
newThread(newRunnable(){
publicvoidrun()?{
Random?r?=newRandom();
for(intj=1;j<1000;j++){
inti?=?r.nextInt(100);
business.write(i);
try{
Thread.sleep(1000);
}catch(InterruptedException?e)?{
e.printStackTrace();
}
}
}
}).start();
}
}
}
//封裝的業務類
classBusiness{
privateintdata=0;//共享資源屬性
privateintreadThreads?=0;//讀線程數
//private?boolean?isWriting??=?false;
//是否執行寫?后來發現不需要?當write搶占鎖時?所有的read?都被擋在synchronized?(this){}之上?無機會執行wait
publicvoidread(){
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();
}
}
publicsynchronizedvoidwrite(inti){
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 寫線程會餓死 這個可以如何解決?
【編輯推薦】
【責任編輯:小林 TEL:(010)68476606】
點贊 0
總結
以上是生活随笔為你收集整理的java怎么写算法_关于读写锁算法的Java实现及思考的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java for循环优化_Java fo
- 下一篇: java 获取操作系统临时目录_获取当前