2012-02-03 4 views
4

は私が定義された2つの方法で「チャンネル」という名前のクラスを持っている:同期パターン

class Channel { 

    void read(){...} 
    void write(){...} 
} 

マルチスレッド環境で使用されるこのクラスのインスタンスがあります。 1つのスレッドが定期的にスレッドに書き込む間に、複数のスレッドがチャネルから定期的に読み取ります。読み取り操作はスレッドセーフであるため、複数の読み取りが同時に行われるようにしても問題ありません。ただし、書き込み操作が開始されると、書き込み操作が終了するまで読み取りスレッドをブロックする必要があります。読み取り操作をできるだけ速く保ち、リソースを消費する同期ルーチンを避けることが不可欠です。

このような動作を実装する最も適切なパターンは何でしょうか?たぶんjavaクラスやライブラリは助ける?

答えて

7

ReadWriteLockを使用してください。これにより、シリアル書き込みで同時読み取りが可能になります。あなたの要件をさらに満たすために、writeLockを入手すると、readLockは次のリリースまで進行しません。

class Channel { 
    final ReadWriteLock lock = new ReentrantReadWriteLock(); 

    void read(){ 
     lock.readLock().lock(); 
     try{ 

     }finally{ 
     lock.readLock().unlock(); 
     } 
    } 
    void write(){ 
     lock.writeLock().lock(); 
     try{ 

     }finally{ 
     lock.writeLock().unlock(); 
     } 
    } 
} 
+1

たぶんJavaの8で、我々は最終的にトライして、リソースがあります:( – stefan

+0

をJavaの7 @stefanはそれだけAutoCloseableを実装するクラスで動作するもののすることを持っている「ん」。Javaの8で出てくるない場合このコードを閉じるともっとよく見える –

+0

ああ、甘い、私はそれが取り出されたと思った。 – stefan

1

は楽しみのために、ここに新しいJava 7のtry-と資源の機能を使用して実装です。

class RWLock { 
    class ACLock extends ReentrantLock implements AutoCloseable { 
     public void close() { 
      this.unlock(); 
     } 
    } 

    private ACLock readLock = ACLock(); 
    private ACLock writeLock = ACLock(); 
    private int numReaders = 0 

    public AutoCloseable write() { 
     readLock.lock(); 
     writeLock.lock(); 
     return new AutoCloseable() { 
      public void close() { 
       writeLock.close(); 
       readLock.close(); 
      } 
     } 
    } 

    public AutoCloseable read() { 
     try (ACLock read = readLock.acquire()) { 
      if (numReaders == 0) { 
       writeLock.lock(); 
      } 
      numReaders++; 
     } 
     return new AutoCloseable() { 
      public void close() { 
       numReaders--; 
       if (numReaders == 0) { 
        writeLock.unlock(); 
       } 
      } 
     } 
    } 

    // Here's how you use them 
    public static void main(String[] args) { 
     RWLock lock = RWLock(); 
     try (AutoCloseable lock = RWLock.read()) { 
      // Do some readin' 
     } 
     try (AutoCloseable lock = RWLock.write()) { 
      // Do some writin' 
     } 
    } 
} 
関連する問題