据我所知,这java.util.Date
是可变的,所以如果多个线程试图访问和修改它,它就不是线程安全的。我们如何使用客户端锁定或组合(包装器)使其成为线程安全的?
问问题
12304 次
4 回答
36
按照这个顺序,从最好到最差:
根本不使用它,请查看 Java 8 的新 Date and Time API。
根本不用,看看jodatime
根本不使用它,使用
AtomicLong
或不可变原语long
来volatile
表示纪元时间封装它。总是返回防御性的副本
Date
,而不是对内部对象的引用Date
在实例上同步。
于 2012-09-03T19:17:03.693 回答
4
您可以使用 long 值(自 Epoch 以来的毫秒数)而不是 Date 实例。分配它将是一个原子操作,并且始终是连贯的。
但是您的问题可能不在于 Date 值本身,而在于整个算法,这意味着真正的答案将基于您的实际问题。
这是多线程上下文中错误操作的示例:
long time;
void add(long duration) {
time += duration;
}
这里的问题是你可能有两个并行添加导致只有一个有效的添加,因为time += duration
它不是原子的(它真的是time=time+duration
)。
使用 long 而不是可变对象是不够的。在这种情况下,您可以通过将函数设置为同步来解决问题,但其他情况可能会更加棘手。
于 2012-09-03T19:18:16.357 回答
2
最简单的解决方案是永远不要修改 Date 并且永远不要共享它。即只对局部变量使用日期。
您可以使用 JodaTime,因为它具有不可变的日期对象。
于 2012-09-03T19:17:58.723 回答
-1
没有简单的解决方案来创建Date
类的线程安全包装器。synchronized
最好的方法是通过使用块来同步它的对象的所有用法。
于 2012-09-03T19:16:57.853 回答