私が知る限り、それjava.util.Date
は可変であるため、複数のスレッドがアクセスして変更しようとした場合、スレッドセーフではありません。クライアント側のロックまたはコンポジション (ラッパー) を使用してスレッドセーフにする方法は?
4 に答える
この順序で、最良のものから最悪のものへ:
まったく使用しないでください。Java 8 の新しい Date and Time APIを確認してください。
まったく使用しないでください。jodatimeをチェックしてください
まったく使用しないでください。
AtomicLong
または不変のプリミティブlong
を使用して、エポック時間volatile
を表しますそれをカプセル化します。
Date
内部オブジェクトへの参照ではなく、常に の防御コピーを返しますインスタンスで同期し
Date
ます。
Date インスタンスの代わりに long 値 (エポックからのミリ秒数) を使用できます。割り当てはアトミック操作であり、常に一貫性があります。
しかし、問題は Date 値自体ではなく、アルゴリズム全体にある可能性があります。つまり、実際の答えは実際の問題に基づいているということです。
マルチスレッド コンテキストでのバグのある操作の例を次に示します。
long time;
void add(long duration) {
time += duration;
}
ここでの問題は、2 つの追加が並行して行われる可能性があり、その結果、効果的な追加が 1 つだけになる可能性があることtime += duration
ですtime=time+duration
。
変更可能なオブジェクトの代わりに long を使用するだけでは十分ではありません。この場合、関数を同期として設定することで問題を解決できますが、他の場合はよりトリッキーになる可能性があります。
最も簡単な解決策は、日付を変更したり共有したりしないことです。つまり、ローカル変数には Date のみを使用します。
不変の日付オブジェクトがあるため、JodaTime を使用できます。
Date
クラスのスレッドセーフなラッパーを作成する簡単な解決策はありません。synchronized
最良の方法は、ブロックを使用してオブジェクトのすべての使用を同期することです。