讀寫者問題-java實現
讀者—寫者問題(Readers-Writers problem)也是一個經典的併發程式設計問題,是經常出現的一種同步問題。計算機系統中的資料(檔案、記錄)常被多個程式共享,但其中某些程式可能只要求讀資料(稱為讀者Reader);另一些程式則要求修改資料(稱為寫者Writer)。就共享資料而言,Reader和Writer是兩組併發程式共享一組資料區,要求:
(1)允許多個讀者同時執行讀操作;
(2)不允許讀者、寫者同時操作;
執行效果:
(1)允許多個讀者同時執行讀操作;
(2)不允許讀者、寫者同時操作;
(3)不允許多個寫者同時操作。
實現的原理:
單純使用訊號量不能解決讀者與寫者問題,必須引入計數器readcount對讀程式計數;readcountsemophore 是用於對計數器readcount 操作的互斥訊號量,之所以引入該訊號量是為了保證原子操作(其實java中有關鍵字synchronized可以實現對塊的原子操作,保證只有一個執行緒來操作該塊,其實這個關鍵字就是封裝了訊號量)。write表示是否允許寫的訊號量;於是讀者優先的程式設計原理如下:
讀者:
while(true)
{
P(rcs);
if(rc==0)
{
rc++;
P(write);
}
V(rcs);
//讀資料
P(rcs)
rc--;
if(rc==0)
V(write);
V(rcs)
}
寫者:
while(true)
{
P(write);
//寫寫寫
V(write);
}
java 實現:
讀者:
import java.util.Random;
import java.util.concurrent.Semaphore;
public class ReadThread extends Thread
{
public int id;// 讀者ID
//public int readCount;// 讀者數量
public Semaphore readCountSemaphore;// 讀者數量訊號量
public Semaphore writeSemaphore;// 寫者訊號量
public ReadThread(int id, Semaphore semaphore,
Semaphore semaphore2)
{
this.id = id;
this.readCount = rcount;
this.readCountSemaphore = semaphore;
this.writeSemaphore=semaphore2;
this.start();// 開始讀
}
//讀者優先
public void run()
{
try
{
//沒人在寫
if(writeSemaphore.availablePermits()>0)//可以讀
System.out.println("讀者"+id+"可以讀...");
else {
System.out.println("有寫者在寫操作,讀者"+id+"等待讀...");
}
// 等待著讀
readCountSemaphore.acquire();
if (<span style="font-family: Arial, Helvetica, sans-serif;">ReadAndWrite.</span>readCount == 0)//如果第一個讀者,那麼要考慮是否有寫者,沒有寫者,直接讀,有寫者,等待寫者
{
//此時不能寫
<span style="font-family: Arial, Helvetica, sans-serif;">ReadAndWrite.</span><span style="font-family: Arial, Helvetica, sans-serif;">readCount</span><span style="font-family: Arial, Helvetica, sans-serif;">++;// 已經具備讀的條件了,讀者數量加1</span>
writeSemaphore.acquire();
}
readCountSemaphore.release();
/**********************************/
//此刻才可以允許其他讀者讀資料
/**********************************/
readCountSemaphore.acquire();
//可以讀了
System.out.println("讀者"+id+"我正在讀哦...");
Thread.sleep((long) (new Random().nextFloat()*2000));
System.out.println("讀者"+id+"讀完了...");
//讀完了,讀者數量減少1
ReadAndrWrite.readCount--;
if(<span style="font-family: Arial, Helvetica, sans-serif;">ReadAndrWrite.</span><span style="font-family: Arial, Helvetica, sans-serif;">readCount==0)//沒有讀者了,可以寫了</span>
{
writeSemaphore.release();
}
readCountSemaphore.release();//釋放讀者訊號量
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
寫者:
import java.util.Random;
import java.util.concurrent.Semaphore;
public class WriteThread extends Thread
{
public int id;//編號
public Semaphore writeSemaphore;//寫者訊號量
public WriteThread(int id,Semaphore semaphore)
{
this.id=id;
this.writeSemaphore=semaphore;
this.start();
}
public void run()
{
try
{
if(writeSemaphore.availablePermits()>0)
{
System.out.println("寫者"+this.id+"可以寫");
}
else
System.out.println("寫者"+this.id+"不可以寫");
writeSemaphore.acquire();
System.out.println("寫者"+this.id+"正在寫...");
Thread.sleep((long) (new Random().nextFloat()*2000));
System.out.println("寫者"+this.id+"寫完了...");
writeSemaphore.release();
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
主程式:
public class ReadAndWrite
{
public static final int count=10;//讀者寫者的數量
public static int readCount=0;
/**
* @param args
*/
public static void main(String[] args)
{
// TODO Auto-generated method stub
Semaphore readCountSemaphore=new Semaphore(1);
Semaphore writeSemaphore=new Semaphore(1);
for(int i=0;i<count;i++)
{
//隨機生成讀者和寫者
if(new Random().nextBoolean())//假設是讀者
new ReadThread(i, readCountSemaphore, writeSemaphore);
else {
new WriteThread(i, writeSemaphore);
}
}
}
}
執行效果:
相關文章
- 讀者-寫著問題中寫者優先的實現
- 有名訊號量實現讀者-寫者問題(讀者優先)
- java實現生產者消費者問題Java
- oracle資料庫版讀者寫者問題Oracle資料庫
- Java實現Kafka讀寫筆記JavaKafka筆記
- java 對word 檔案的讀寫問題Java
- Java Thread實現讀寫同步 (轉)Javathread
- 線上MySQL讀寫分離,出現寫完讀不到問題如何解決MySql
- socket 實現的 web 伺服器在 Windows 下的讀寫問題Web伺服器Windows
- 漢羅塔問題 java實現Java
- Java實現-揹包問題IJava
- Java實現-揹包問題IIJava
- Java實現-揹包問題VIJava
- 關於Java多執行緒實現生產者和消費者的問題Java執行緒
- 作業系統實驗——讀者寫者模型(寫優先)作業系統模型
- java多執行緒總結六:經典生產者消費者問題實現Java執行緒
- Java實現在訪問者模式中使用反射Java模式反射
- Java 併發包中的讀寫鎖及其實現分析Java
- 通過STANDBY資料庫實現讀寫分離時索引過多的問題資料庫索引
- Amoeba實現讀寫分離
- Java讀取File的問題Java
- Java.nio-隨機讀寫解決漢字亂碼問題Java隨機
- 有名訊號量實現消費者生產者問題
- 生產者消費者問題-C++程式碼實現C++
- java實現pv操作 -------哲學家問題Java
- 關於STM8的使用者資料空間讀寫問題
- Thinking in Java---執行緒通訊+三種方式實現生產者消費者問題ThinkingJava執行緒
- Java 讀檔案寫檔案 韓文 中文 亂碼問題解決方案Java
- ProxySQL實現MySQL讀寫分離MySql
- Amoeba 實現 MySQL 讀寫分離MySql
- CQRS如何實現讀寫分離
- java讀資原始檔的問題Java
- Java訊號量實現程式同步問題:水果蘋果香蕉問題Java蘋果
- JAVA實現附近範圍內公交定位問題Java
- java中實現報表樣式的問題Java
- 經典n皇后問題java程式碼實現Java
- java web start實現關鍵問題(二) (轉)JavaWeb
- 轉:13球稱重問題Java實現 收藏Java