2011-11-16 5 views
0

は、次のコードsnipetを考えてみましょう:てexecutor.executeは()JMM保証

public class A { 

    private final Executor executor = Executors.newCachedThreadPool(); 
    private final Queue<Object> messageQueue = new ConcurrentLinkedQueue<M>(); 

    public void sendMessage(Object message) { 
     messageQueue.offer(message); 
     executor.execute(new Runnable() { 
      @Override 
      public void run() { 
       final Object message = messageQueue.poll(); 

       // Can message == null? 
      } 
     }); 
    } 
} 

それはメッセージキューはRunnableをインスタンスがそれを取得しようとする時間によってメッセージが含まれていることを保証しますか? JMMによれば、2つの関数呼び出しをJIT/JVMで並べ替えることはできますか?

答えて

4

はい、他のプロデューサ/コンシューマが存在しない場合はあります。

Executor.execute()確立するする前にの関係。したがって、offer()のすべては、poll()の前に発生します。 poll()offer()の効果があります。正式には指定されていませんが、poll()はキューに追加されたばかりのオブジェクトを返す必要があります。

+0

Executor.execute()の関係が保証される前に、これが発生するドキュメントへの参照を提供してください.Javadocのhttp://download.oracle.com/javase/1 、5.0/docs/api/java/util/concurrent/Executor.html –

+1

事実上の関係は文書化されていますが、Java 6から始まります。 "メモリ一貫性の影響:Runnableオブジェクトをエグゼクティブは、その実行が始まる前に、おそらく別のスレッドで発生します。 http://download.oracle.com/javase/6/docs/api/java/util/concurrent/Executor.html ありがとう、Mr. Irreputable :) –

-1

通話を同期していないため、注文の内容が保証されません。 VMの実装や基盤となるOSアーキテクチャーによっては、Nullメッセージオブジェクトで終了する可能性もあります。私は、異なるプラットフォームで作業するときに、いくつかの厄介な驚きを経験しました。これらのプラットフォームのスレッド実装が異なるためです。

また、コードの残りの部分と同期している場合でも、messageQueueが空である可能性があることにも気付きます。あなたの選択したプラットフォームで動作しているように見えても、呼び出しが同期していない可能性があり、この種の発生を防ぐためには、賢明に思えます。

おそらく、Java Concurrency Frameworkのドキュメントを順を追って読んで、これらの種類のコーディングの問題に対して非常に洗練された解決策を提供するかもしれません。 Java Concurrency Framework

関連する問題