3
public class IntermediateMessage {

    private final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
    private final Lock read = readWriteLock.readLock();
    private final Lock write = readWriteLock.writeLock();

    private volatile double ratio;

    public IntermediateMessage(){
        this.ratio=1.0d;
    }

    public IntermediateMessage(double ratio){
        this.ratio = ratio;
    }

    public double getRatio(){
        read.lock();
        try{
            return this.ratio;
        }
        finally{
            read.unlock();
        }
    }

    public void setRatio(double ratio){ 
        write.lock();
        try{
            this.ratio = ratio;
        }
        finally{
            write.unlock();
        }
    }
}

私はこのオブジェクトを持っています。アプリケーションにこのオブジェクトのインスタンスがあり、1 つのスレッドが比率変数に書き込み、他のスレッドが比率を読み取っています。比率変数を保護するこれは正しい方法ですか? ratio を volatile として宣言する必要がありますか?

4

5 に答える 5

1

そもそもロックが必要ですか?あなたが説明した限られた要件によると、おそらくそうではありません。しかし、これを読んで確認してください...

  • あなたが書いているスレッドは 1 つだけです。
    • これは、競合するライターが互いに「上書き」しているために、変数値が「時代遅れ」になることは決してないことを意味します (競合状態の可能性はありません)。 したがって、個々の変数を分離して検討する場合、整合性を確保するためにロックは必要ありません。
  • 複数の変数の何らかの形式のアトミックで一貫した変更が必要かどうかについては言及していません。そうではないと思います。
    • IFratioは常に他の変数(たとえば、他のオブジェクト内) と一致している必要があります。つまり、変数のセットがグループとして同期して変更され、変更の一部だけを読み取る人がいない場合、ロックは、変数のセットにアトミックな一貫性を与えるために必要です。変数. 次に、一貫した変数を単一のロックされた領域内で一緒に変更する必要があり、リーダーはこれらの変数のセットを読み取る前に同じロックを取得する必要があります (必要に応じて、ブロックされた状態で待機します)。
    • IF 比率は、単独の変数としていつでも変更でき、他の変数との一貫性を維持する必要はありません。ロックは必要なく、一連の変数にアトミックな一貫性を与えます

volatile 修飾子が必要ですか? はい、そうです!

  • 複数のスレッドを読んでいます。
  • 変数は、読み取られる直前の瞬間を含め、いつでも変更できます。
  • volatile修飾子はマルチスレッド アプリで使用され、「リーダー」によって読み取られた値が「ライター」によって書き込まれた値と常に一致することを保証します。
于 2013-05-29T04:59:01.043 に答える
1

同期で過剰な処理を行っているため、効率が低下します。

Java キーワードの「volatile」は、変数がキャッシュされず、複数のスレッドのアクセスが同期されることを意味します。

したがって、デフォルトですでに同期されている変数をロックしています。

したがって、volatile キーワードを削除するか、再入可能ロックを削除する必要があります。現在同期している方法で複数の読み取りを行うと、より効率的になるため、おそらく揮発性です。

于 2013-05-29T01:23:21.387 に答える