如何使 java.util.Date 线程安全

2022-09-02 12:00:47

据我所知,这是可变的,所以如果多个线程尝试访问和修改它,它就不是线程安全的。我们如何使用客户端锁定或组合(包装器)来使其线程安全?java.util.Date


答案 1

按此顺序,从最佳到最差:

  1. 根本不使用它,请查看Java 8的新日期和时间API

  2. 根本不使用它,请查看

  3. 根本不使用它,使用或不可变的基元来表示纪元时间AtomicLonglongvolatile

  4. 封装它。始终返回 的防御性副本,从不引用内部对象Date

  5. 在实例上同步。Date


答案 2

您可以使用长整型值(自纪元以来的毫秒数)而不是 Date 实例。分配它将是一个原子操作,它将始终是连贯的。

但是你的问题可能不在于 Date 值本身,而在于整个算法,这意味着真正的答案将基于你真正的问题。

下面是多线程上下文中的错误操作示例:

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

这里的问题是,你可能有两个并行加法,导致只有一个有效的加法,因为不是原子的(它真的是)。time += durationtime=time+duration

使用 long 而不是可变对象是不够的。在这种情况下,您可以通过将函数设置为同步来解决问题,但其他情况可能更棘手。


推荐