0

この式が正しいかどうか、また、これが意味することかどうかを知りたいです。フィールド ステータスに書き込みロックを設定し、それを変更します。そうでない場合は、常にthisが表示されるため、パラメーターの意味を知りたいです。

public class Example {
    private int status;
    public Example(int status){
        this.status = status;
    }
    public void setStatus(int newStatus){
        synchronized(this.status){
            this.status = newStatus;
        }
     }
}
4

3 に答える 3

5

このコードにはいくつか問題があります。

  1. synchronizeプリミティブではできません。

    に変更できますが、Integer以下を参照してください。

  2. 非最終オブジェクトで同期することはお勧めできません。

    あなたはそれを作ることができましたfinal

  3. オンになっているフィールドを変更するとsynchronized、いくつかの非常にあいまいな方法で壊れます。そして今、それはfinal許可されません。

    おそらく別のフィールドで同期する方が良いでしょう。

  4. 完全を期すために get メソッドも提供する必要があります。

これらの問題をすべて修正すると、コードは次のようになります。

public class Example {
  private final Object statusLock = new Object();
  private Integer status;

  public Example(Integer status) {
    this.status = status;
  }

  public void setStatus(Integer newStatus) {
    synchronized (statusLock) {
      status = newStatus;
    }
  }


  public Integer getStatus() {
    return status;
  }
}

さて、このコードで、あなたの質問に対する答えは一種の. ここで起こることは、値を変更している間、他のスレッドからset メソッドを介してフィールドへのすべてのアクセスをロックすることです。status

get メソッドで同期しないことに注意してください。もしそうなら、上記の声明は変わるでしょう。

于 2013-10-03T08:56:27.580 に答える
0

いいえ、あなたの表現はあなたの考えを意味するものではありません。同期ブロックのパラメーターは、同期ブロックを実行する前に取得し、最後に解放するロックです。Java では、Object から継承するすべてのものをロックとして使用できます (つまり、ロックとしてint使用できません)。

一度にロックを保持できるスレッドは 1 つだけですが、異なるオブジェクトがパラメーターとして指定されている場合、同じ同期ブロック内のコードを複数のスレッドで同時に実行できます。一方、2 つの異なる同期ブロックにパラメーターとして同じロックが与えられている場合、2 つのスレッドは異なる同期ブロックから異なるコードを実行できません。

人々thisはロックとして使用することがよくありますが、特にロックを目的としたオブジェクトを使用することも一般的です。

于 2013-10-03T09:06:31.043 に答える
0

であるフィールドを同期していることがわかりましthis.statusint。プリミティブ型で同期することはできません。オブジェクトまたはクラスのみ。

の使用を検討してみませんかAtomicInteger:

    public class Example
{
  private AtomicInteger status;

  public Example(int status)
  {
    this.status = new AtomicInteger(status);
  }

  public void setStatus(int newStatus)
  {
    this.status.getAndSet(newStatus);
  }
}
于 2013-10-03T08:56:35.370 に答える