2015-11-23 9 views
8

はコードです:私たちは、単に数を取得するためにqueue.size()を使用できるようこのコードでは、Collection.size()を使用してカウンタを置き換えることはできますか?ここ

public class LogService { 
    private final BlockingQueue<String> queue; 
    private final LoggerThread loggerThread; 
    private final PrintWriter writer; 
    @GuardedBy("this") private boolean isShutdown; 
    @GuardedBy("this") private int reservations; // <-- counter 
    public void start() { loggerThread.start(); } 
    public void stop() { 
     synchronized (this) { isShutdown = true; } 
     loggerThread.interrupt(); 
    } 
    public void log(String msg) throws InterruptedException { 
     synchronized (this) { 
      if (isShutdown) 
       throw new IllegalStateException(...); 
      ++reservations; 
     } 
     queue.put(msg); 
    } 
    private class LoggerThread extends Thread { 
     public void run() { 
      try { 
       while (true) { 
        try { 
         synchronized (LogService.this) { 
          if (isShutdown && reservations == 0) 
           break; 
         } 
         String msg = queue.take(); 
         synchronized (LogService.this) { 
          --reservations; 
         } 
         writer.println(msg); 
        } catch (InterruptedException e) { /* retry */ } 
       } 
      } finally { 
       writer.close(); 
      } 
     } 
    } 
} 

それが本の練習でのJava並行処理からの抜粋だ、と私はそれについて考えているかもしれないカウンターreservationsは不要ですqueueの要素。

私は正しいですか?

+1

キュー 'put'と' get'は同期していません。 '予約'が変更されました。 –

答えて

5

いいえ、実際にはデッドロックが発生します。

sizeを並列に使用する場合は、puttakeを同期させる必要があります。しかしtakeがブロックされ、put呼び出しと同じオブジェクトに対してブロックtake呼び出しが同期されるようになりました。 takeは、何かがputになるまで取ることができません。 putはロックを放棄するまでtakeまで置くことができません。それはデッドロックです。 「予約」を使用して

+0

私は 'put'と' take'メソッドのソースコードを見て、 'Lock'と同期しているようです。 – user2916610

+0

@ user2916610 'size'も同期されていれば問題になります。 – djechlin

+0

'size'も同期しています。 – user2916610

0

変数が良いドメイン設計がはるかに有意義なサイズよりもそれがされているためで、パフォーマンスの面で利用できる予約など

の総数のようなドメインの概念を表現するためにそれを使用することができます

ArrayBlockingQueue - 呼び出しサイズ関数は、サイズを読み取るためにロックを取得し、takeまたはput操作も遅くなるため遅くなります。

LinkedBlockingQueue - 呼び出しサイズはアトミック/揮発性読み取りであり、パフォーマンスコストがあります。

関連する問題