19

私が知る限り、それjava.util.Dateは可変であるため、複数のスレッドがアクセスして変更しようとした場合、スレッドセーフではありません。クライアント側のロックまたはコンポジション (ラッパー) を使用してスレッドセーフにする方法は?

4

4 に答える 4

36

この順序で、最良のものから最悪のものへ:

  1. まったく使用しないでください。Java 8 の新しい Date and Time APIを確認してください。

  2. をチェックしてください

  3. まったく使用しないでください。AtomicLongまたは不変のプリミティブlongを使用して、エポック時間volatileを表します

  4. それをカプセル化します。Date内部オブジェクトへの参照ではなく、常に の防御コピーを返します

  5. インスタンスで同期しDateます。

于 2012-09-03T19:17:03.693 に答える
4

Date インスタンスの代わりに long 値 (エポックからのミリ秒数) を使用できます。割り当てはアトミック操作であり、常に一貫性があります。

しかし、問題は Date 値自体ではなく、アルゴリズム全体にある可能性があります。つまり、実際の答えは実際の問題に基づいているということです。

マルチスレッド コンテキストでのバグのある操作の例を次に示します。

long time;
void add(long duration) {
   time += duration; 
}

ここでの問題は、2 つの追加が並行して行われる可能性があり、その結果、効果的な追加が 1 つだけになる可能性があることtime += durationですtime=time+duration

変更可能なオブジェクトの代わりに long を使用するだけでは十分ではありません。この場合、関数を同期として設定することで問題を解決できますが、他の場合はよりトリッキーになる可能性があります。

于 2012-09-03T19:18:16.357 に答える
2

最も簡単な解決策は、日付を変更したり共有したりしないことです。つまり、ローカル変数には Date のみを使用します。

不変の日付オブジェクトがあるため、JodaTime を使用できます。

于 2012-09-03T19:17:58.723 に答える
-1

Dateクラスのスレッドセーフなラッパーを作成する簡単な解決策はありません。synchronized最良の方法は、ブロックを使用してオブジェクトのすべての使用を同期することです。

于 2012-09-03T19:16:57.853 に答える