5

次のような別のスレッドから更新された JavaBeanユーザーがあるとします。

public class A {

    private final User user;

    public A(User user) {
        this.user = user;
    }

    public void aMethod() {
        Thread thread = new Thread(new Runnable() {

            @Override
            public void run() {
                ...a long running task..
                user.setSomething(something);
            }

        });
        t.start();
        t.join();
    }

    public void anotherMethod() {
        GUIHandler.showOnGuiSomehow(user);
    }
}

このコードはスレッドセーフですか? つまり、A インスタンスを作成して A.aMethod を呼び出したスレッドがユーザー フィールドを読み取るとき、ユーザーが新しい状態で表示されるのでしょうか? 適切なスレッドセーフな方法でそれを行うには?

ユーザークラスを変更することはできず、それ自体がスレッドセーフかどうかもわかりません。

4

6 に答える 6

4

finalフィールドを単なるものとしてマークすると、参照を変更できないことを意味します。class のスレッドの安全性については何も意味しませんUser。フィールドにアクセスするこのクラスのメソッドが同期されている (または他の同期手法を使用している) 場合、スレッドセーフです。そうでなければそうではありません。

于 2013-05-23T08:40:55.733 に答える
4

このコードはスレッドセーフですか? ... ユーザーが新鮮な状態で表示されますか?

特にありません-userコードで最終的な事実は、それを置き換えることができないという事実を除いて、スレッドセーフにほとんど違いはありません。

変更する必要があるビットは、によって設定されるインスタンス変数ですsetSomething。としてマークする必要がありますvolatile

class User {
  // Marked `volatile` to ensure all writes are visible to other threads.
  volatile String something;

  public void setSomething(String something) {
    this.something = something;
  }

}

ただし(お勧めのように)クラスにアクセスできない場合Userは、メモリバリアを作成する同期を実行する必要があります。user最も単純な形式では、へのアクセスをアクセスで囲むことができsynchronizedます。

synchronized (user) {
  user.setSomething(something);
}

追加:- これは実際には次のように実行できることがわかりました (ここを参照)。

volatile int barrier = 0;
...
user.setSomething(something);
// Forces **all** cached variable to be flushed.
barrier += 1;
于 2013-05-23T08:37:52.783 に答える
0

ユーザークラスを変更することはできず、それ自体がスレッドセーフかどうかもわかりません。

User オブジェクトにアクセスするときは、アクセスを同期する必要があります。たとえば、User オブジェクトを使用して同期することができるため、ユーザー オブジェクトへのすべてのアクセスを次のようにラップするだけです。

synchronized(user) {
  // access some method of the user object
}

これは、ユーザー オブジェクトがスレッド内で非同期にのみアクセスされることを前提としています。また、同期ブロックを短くしてください。

ユーザー オブジェクトの周りにスレッド セーフなラッパーを作成することもできます。さまざまな呼び出しが多数ある場合は、コードがよりクリーンになり、そのように読みやすくなることをお勧めします。

幸運を!

于 2013-05-23T09:52:19.757 に答える