2012-05-08 39 views
0

私のクラスでは、私の「タスク」クラスのように動作するコードを以下に示します。私は、このクラスのインスタンスを複数作成し、threadpoolJavaでDTOオブジェクトを使用するときのスレッドの安全性

class Task { 

    public void doJob() { 

     String s = informationDto.getName(); 

    } 
} 

DTOに渡します:私はinformationDto.getName();声明について疑問に思って

class InformationDto{ 

    private String name; 

    public getName(){} 

    public setName(String n){} 

} 

。マルチスレッド環境では常に正しい名前が返されますか?

getName()方法は静的なものである場合、何が起こりますか?

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

1)Taskクラスごとに1つずつInformationDtoとします。 2)インスタンス変数はスレッドセーフではないので、私はTaskクラスに設定した正しい名前を得ることができるでしょうか?getName()メソッド(nameはインスタンス変数です)にアクセスすればいいのですか? 3)スレッドセーフなクラスであるTaskクラスの中でutilクラスを使用するのと同じですか?スレッドセーフな方法でutilのインスタンスの種類を使用する方法はありますか?私はまだ正確にあなたの問題について明確が、コメントで言っただけでは不十分だ

+1

"正しい名前"とはどういう意味ですか?誰かが 'setName()'を同じインスタンス上で並列に呼び出すでしょうか? 'InformationDTO'が不変である必要がありますか?あなたの質問に合うかもしれないいくつかの答えがありますので、多少の背景を与えるでしょうか? –

+0

'InformationDto'は不変クラスではありません。それは普通のDTOです。だから私はどのようにスレッドセーフな方法でそのDTOを使用することができますか?つまり、 'Task'クラスのメソッド変数でそれを使用しているので、スレッドセーフなのでしょうか?私は 'doJob'メソッドの中で' DTO'のインスタンス変数にアクセスしているからです。 – Sam

+0

スレッドセーフとは、予期しない同時変更が発生しないことを意味します。別のスレッドがコレクションを変更している間、コレクションを反復するようなものです。あなたの場合、 'setName()'がそれを変更できる間、 'getName()'は内部状態を返します。誰かが新しい文字列の半分と古い文字列の半分を持っているように、それを更新している人の途中でその状態を部分的に読むことはできませんが、 'setName() '。それで私の質問。あなたはどんなふうに行動しますか?この文脈であなたにとってスレッドセーフであることを定義してください –

答えて

4

、あなたに答えを与えることをしようとします。

私はgetName()はこのないと仮定します:

public getName() { 
    return name; 
} 

setName()がこれを行う:

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

によって使用されるこのクラスのインスタンスを持つ
private String name; 

を複数のスレッドは、誰もがwilを保証するものではありません彼らがsetName()を他の人が働いている間に誰も電話しないことが保証されるまで、彼らがgetName()と尋ねるときに同じことを見る。

getName()が一貫して同じ値を返すように保証する1つの方法は、ロックすることです。

private final name; 

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

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

マルチスレッド環境でこのインスタンスに何が起こる可能性がありますか?あまりない。 getName()は、古い値の半分と新しい値の半分が別のスレッドによって書き込まれているなど、部分的な状態を返さないでしょう。あなたはそこでは安全です。 getName()を静的にすることはあまり変わらない。これはクラスメソッドになります。namestaticになっているインスタンスメソッドではなく、あなたの裏庭では望ましくない大域状態です。

これはあなたの質問に答えるか、少なくともあなたの次のステップを把握するのに十分な手がかりを与えます。

更新

private volatile String name; 

volatileを使用して保証されます:あなたはnameが変化し、すべてのスレッドが最新の値を読んでメンバ変数を宣言するとき、あなたはvolatileを使用できることを確認したいことを期待するならば、それは、コメントで指摘されたと同じようにyour threads "communicate" on modification events and don't trust their local caches

+0

'name'の新しい値が他のスレッドによって見られることは保証されませんフィールドはvolatileとマークされるか、または他の形式の同期を使用します。 – Jeremy

+1

@Samは並行処理を扱うより基本的なアドバイスを探していたようだ。とにかくより完全な答えを更新します。ありがとう –

+0

@PavelVeller - ありがとう、あなたの答えです。ですから、 'setter'メソッドを使うのではなく、'コンストラクター '注入を行うようになります。あなたの答えは私のためにそれをクリアしました。ありがとう。 – Sam

関連する問題