2009-04-01 8 views
2

スレッドをキャンセルするための通常の協調メカニズムを実装したいと考えています。 しかし、私がJDK5以前の環境にいる間は、JavaメモリーモデルはJDK5でのみ修正されていました。 私は、これはSCIPで信じられているように、このようなことが正しいとは限りません。パフォーマンスが最も低い揮発性物質の代替品

class Worker implements Runnable 
{ 
    private volatile boolean _canceled; 

    public void cancel() { _canceled = true; } 

    public void run() { 
     while(! _canceled) 
     { 
      // do my Stuff 
     } 
    } 
} 

私はAtomicBooleanを使用して_canceled変数をカプセル化することを考えています。 他の方法はありますか?

答えて

3

AtomicBooleanもJDK5で追加されました。backportを使用していない限り、これは利用できません。しかし、はい、バックポートの原子クラスは、JVM仮想マシン仕様の各バージョンで動作することに精通している人が書いたことが分かっているように、最良の選択かもしれません。

+0

バックポートコードを見ていきます。ありがとう –

0

AtomicBooleanがJava 5よりも前に使用可能だったとは思いません。プライベートブールフィールドでの同期はどうですか?

+0

"最も安いパフォーマンスヒット"という質問の一部は間違っています。どのJDK5以前のバージョンが使用されているかに応じて、同期化は比較的高価になります。 – Eddie

3

私がFAQを正しく理解している場合、これは揮発性フィールドの並べ替えを可能にする古いメモリモデルでは問題ありません。これらの例では、古いモデルでは、JVMに基づいて「x」が0または42のいずれかになります。経験則では、並べ替えは常にコンパイラ/ CPUによってパフォーマンスが向上するはずですが、プログラマには見えません。古いモデルはそのルールを破った。

あなたの例では、そのvisabilityの問題を受けてはならないと

+0

それは私もそれを読む方法です。この例のcancel()メソッドが_canceledを設定する前に他の(不揮発性の)フィールドを設定した場合、run()メソッドはループを終了するときに新しい値を保証することはできません。しかし、書かれているように、この例はうまくいくでしょう。 –

+0

私がJava 1.1で動作していると言ったらどうでしょうか –

+0

あなたの不幸を笑うでしょうが、私は答えを変えません。参照:http://books.google.com/books?id=AGiNvDefyFEC&pg=PA493&lpg=PA493&dq=%22Java+1.1%22+volatile&source=bl&ots=gNk5wPQ5Tx&sig=Ik52-18xQ4670sqVw8A2PDwN83E&hl=en&ei=z1HUSe6sGaToswPtoN2xCg&sa=X&oi=book_result&ct=result&resnum=6 –

1

IIRCは、非常に古い日のJREがまったく揮発実装されていませんでしたに働くだろう。賢明に試みると、古いJMMはこの種の方法で揮発性物質を使用することを可能にしています(使用できる唯一の方法について)。私はSun 1.4 JREが1.5 JMMを実際に実装していることを理解しています。違いはバグとみなされます。