Как сделать Java.util.Date потокобезопасным

Насколько я знаю, что java.util.Date изменен, поэтому он не является потокобезопасным, если несколько потоков пытались получить доступ и изменить его. Как мы используем блокировку или компоновку на стороне клиента (обертку), чтобы сделать ее потокобезопасной?

Ответы

Ответ 1

В этом порядке, от лучшего к худшему:

  • Не использовать его вообще, посмотрите

  • Не использовать его вообще, используйте AtomicLong или неизменяемый примитив long с volatile для представления времени эпохи

  • Инкапсулируйте его. Всегда возвращайте защитную копию Date, никогда не ссылаясь на внутренний объект

  • Синхронизировать с экземпляром Date.

Ответ 2

Вы можете использовать длинное значение (миллисекунды с эпохи) вместо экземпляра даты. Присвоение его будет атомной операцией, и оно всегда будет связным.

Но ваша проблема, возможно, не в самом значении Date, а во всем алгоритме, что означает, что реальный ответ будет основан на вашей реальной проблеме.

Вот пример работы с ошибкой в ​​многопоточном контексте:

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

Проблема заключается в том, что вы можете иметь два дополнения параллельно, что дает только одно эффективное дополнение, потому что time += duration не является атомарным (это действительно time=time+duration).

Использование длинного вместо изменяемого объекта недостаточно. В этом случае вы можете решить проблему, установив функцию как синхронизированную, но другие случаи могут быть более сложными.

Ответ 3

Самое простое решение - никогда не изменять дату и не делиться ею. т.е. Используйте только дату для локальных переменных.

Вы можете использовать JodaTime, поскольку он имеет неизменяемые объекты даты.

Ответ 4

Нет простого решения для создания потокобезопасной оболочки класса Date. Лучший способ - синхронизировать все его применения с помощью блоков synchronized.