據我所知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