1

「タスク」クラスのように機能するクラスに、以下のようなコードがあります。このクラスの複数のインスタンスを作成し、threadpool

class Task {

    public void doJob() {

        String s = informationDto.getName();

    }
}

DTO:

class InformationDto{

    private String name;

    public getName(){}

    public setName(String n){}

}

informationDto.getName();発言が気になります。マルチスレッド環境では常に正しい名前が返されますか?

getName()メソッドが静的な場合はどうなりますか?

私が作成しているすべてのクラスinformationDtoにそれぞれを使用したい。Taskこれを行う最良の方法は何ですか?

1)クラスInformationDtoごとに 1 つ保持したい。Task2) インスタンス変数はスレッドセーフではないのでgetName()、メソッドにアクセスするかどうか疑問に思っています (インスタンス変数であるため)、クラスnameに設定した正しい名前を取得できますか? Task3)クラス内でutilクラスを使用するTaskと、スレッドセーフになりますか?そうでない場合、スレッドセーフな方法でユーティリティインスタンスの種類を使用するにはどうすればよいですか?

4

1 に答える 1

4

私はまだあなたの問題について正確には明確ではありませんが、コメントで十分に述べられているので、答えを出そうとします.

私はこれを行うと仮定getName()します:

public getName() {
    return name;
}

そしてsetName()これを行います:

public setName(String name) {
    this.name = name;
}

どこにnameある:

private String name;

getName()このクラスのインスタンスを複数のスレッドで使用しても、他のスレッドが動作しているときに誰もそれを呼び出さないことが保証されるまでは、誰もが同じものを見ることは保証されませんsetName()

getName()が一貫した同じ値を返すことを保証する 1 つの方法は、ロックダウンすることです。これを行うには、オブジェクトを不変にします。

private final name;

public InformationDTO(String name) {
  this.name = name;
}

この方法nameは変更されないことが保証されており、誰もオブジェクトを変更できないことがわかっているため、必要な数のスレッドにオブジェクトを安全に渡すことができます。ただし、これにより、そのプロパティを設定できないという意味で、完全な POJO にはなりません。setName()(直接またはある種のフレームワークを介して間接的に)使用できるようにする必要がある場合、これはあなたのためにそれを行いません.

マルチスレッド環境でこのインスタンスを使用すると、他に何が問題になる可能性がありますか? あまりない。古い値のgetName()半分と新しい値の半分が別のスレッドによって書き込まれているような、部分的な状態は返されません。あなたはそこで安全です。静的getName()にすることはあまり変わりません。これは、インスタンス メソッドではなく、クラス メソッドにnameなりstaticます。これは、バックヤードでは望ましくない、非常にグローバルな状態になります。

これがあなたの質問に答えるか、少なくとも次のステップを理解するのに十分な手がかりを与えることを願っています.

更新します。コメントで指摘されたように、name変更が予想され、すべてのスレッドが最新の値を読み取るようにしたいvolatile場合は、メンバー変数を宣言するときに使用できます。

private volatile String name;

を使用volatileすると、変更イベントでスレッドが「通信」し、ローカル キャッシュを信頼しないようになります

于 2012-05-08T03:14:31.187 に答える