2011-11-14 9 views
3

これは私たち(私と私の同僚)がここで直面する古典的な並行性の問題です。私たちは怠け者ではありませんでした。あなたが適切に手助けをするために関連コードを持ってきました。私たちは、リーダーとライターを定義する2つのクラスを持っている 、彼らは両方の Threadクラスを拡張し、そしてもちろんそのようrunメソッドをオーバーライドします。Javaセマフォを使用した読者/ライターの解読

while(!isInterrupted()) { 
try{ 
    Thread.sleep(for some time) 
}catch(InterruptedException e) {} 

database.readLock(); 
    readersWorking++; //for debugging purposes 
database.readUnlock(); 
} 

ライターのrunメソッドはほとんど同じですが、我々はwritersWorkingをインクリメントしていますデバッグの目的でも使用できます。

主な方法では、20人の読者と2人の作家を作成しています。彼らは両方とも、コンストラクタの注入によってDatabaseクラスのインスタンスを1つ取得します。

class Database { 
    Semaphore writeMut = new Semaphore(1); 
    Semaphore readMut = new Semaphore(1); 
    private int readersWorking = 0; 

    public Database() { 

    } 

    public void readLock() { 
     readMut.acquireUninterruptibly(); 

     if(readersWorking==0) //Am I the first one? 
      writeMut.acquireUninterruptibly(); 
     readersWorking++; 

     readMut.release(); 
    } 

    public void writeLock() { 
     writeMut.acquireUninterruptibly(); 
    } 

    public void readUnlock() { 
     readMut.acquireUninterruptibly(); 
     readersWorking--; 
     if(readersWorking==0) //Am I the last one? 
      writeMut.release(); 
     readMut.release(); 
    } 

    public void writeUnlock() { 
     writeMut.release(); 
    } 
} 

質問:なぜこのコードは、読者がデータベースにアクセスしている間にライターがまだその中にいる間、その逆になりますか?これをどうやって否定することができますか?ここで私たちの論理に何が間違っていますか?誰もが知っているなら、Javaの並行性に関する良い本を探しています。

提供されたコードが十分ではありません念のため、ここでは完全なコードがあります:http://codepad.org/IJ7e145C

+0

あなたはいくつかの読者を持っているようです。これはあなたのデバッグ統計を混乱させないと確信していますか? – Tudor

答えて

5

私は(怠惰な、私は知っている:p)を徹底的にあなたのコードを解析するために気分で実際にないんだけど、それが聞こえますjava.util.concurrent.locksパッケージのように、exactly what you needがかなりあります。さて、あなたがJava 1.4に執着していない限り、私はあなたにこの厄介な作業をさせるために、Javaの並行性ユーティリティに頼ることを強くお勧めします。あなたは自分で簡単にするでしょう。

本はthis will fit the billのようです。

+0

ビッグ+1。 Javaの同時実行性utilsを使用し、Java Concurrency in Practiceを入手してください。 – user949300

+0

Huh ...そのリンクは、最初からOutputStreamを指していましたか? EJPと同じようにReadWriteLockされているはずです。混乱して申し訳ありません、私はそれを編集しました。 –

関連する問題