Как сделать Java.util.Date потокобезопасным
Насколько я знаю, что java.util.Date
изменен, поэтому он не является потокобезопасным, если несколько потоков пытались получить доступ и изменить его. Как мы используем блокировку или компоновку на стороне клиента (обертку), чтобы сделать ее потокобезопасной?
Ответы
Ответ 1
В этом порядке, от лучшего к худшему:
-
Не использовать его вообще, посмотрите jodatime
-
Не использовать его вообще, используйте 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
.