据我所知java.util.Date
是可变的,所以如果多线程试图访问和修改它,它就不是线程安全的。我们如何使用客户端锁定或组合(包装)来使其线程安全?如何使Java.util.Date线程安全
回答
按照此顺序,从最好到最差:
不使用它在所有的,看看jodatime
不使用它在所有使用
AtomicLong
或一成不变的原始long
与volatile
代表时代封装它。总是返回
Date
的防御副本,从不参考内部对象同步于
Date
实例。
没有简单的解决方案来创建Date
类的线程安全封装。最好的方法是使用块同步它的所有对象。
然后你需要携带这个同步块,无论你使用它。这在实践中不是很好吗? – peter
代码很糟糕。这就是为什么Tomasz的回答比我的要好得多;) –
最简单的解决方法是永远不要修改日期并永远不会共享它。即只对本地变量使用日期。
您可以使用JodaTime,因为它具有不可变的日期对象。
您可以使用long值(Epoch以来的毫秒数)而不是Date实例。分配它将是一个原子操作,它始终是连贯的。
但是,您的问题可能不是日期值本身,而是整个算法,这意味着真正的答案将基于您真正的问题。
这里的越野车运行在多线程上下文中的例子:
long time;
void add(long duration) {
time += duration;
}
这里的问题是,你可能有导致只有一个有效的另外两个平行的增加,因为time += duration
不是原子(它真的time=time+duration
)。
使用long而不是可变对象是不够的。在这种情况下,您可以通过将函数设置为同步来解决问题,但其他情况可能会更棘手。
- 1. 如何使线程安全,而不是线程安全
- 2. java线程安全:线程安全吗?
- 3. 如何使缓存线程安全
- 4. 如何使Roles.ApplicationName线程安全?
- 5. 如何使这个线程安全
- 6. 如何使JavaFX的线程安全Platform.runLater
- 7. 如何使Stack.Pop线程安全
- 8. 如何使SqlDataReader线程安全/转换为线程安全类型
- 9. 部分线程安全是否使Java类线程安全?
- 10. 使用线程安全或非线程安全的PHP?
- 11. 线程安全
- 12. 线程安全
- 13. 线程安全
- 14. 线程安全
- 15. 线程安全
- 16. 线程安全
- 17. 线程安全
- 18. 线程安全
- 19. 线程安全
- 20. 线程安全
- 21. 使属性线程安全
- 22. 使可变线程安全
- 23. 使用线程安全库
- 24. 线程安全使用CallContext.LogicalSetData
- 25. 线程安全的程序如何包含非线程安全的类?
- 26. 如何修复PHP模块线程安全/非线程安全的不匹配?
- 27. 如何使循环队列完全线程安全
- 28. 线程安全应用程序中的线程安全
- 29. 线程安全:: random_device
- 30. 线程安全singelton
如果我们已经在这里,'GregorianCalendar'和'SimpleDateFormat'也不是线程安全的。总是值得提醒。 –
感谢提醒 – peter