Java LocalTime 实现线程安全

Far*_*raz 0 java java-time

LocalTime 的文档说它是线程安全的。我知道它本身就是线程安全的。但是,如果我要在像这样的多个线程之间共享它,它会是线程安全的吗?

public class Timesheet {

private static boolean run = true;

private static LocalTime activity;

public static void main(String[] args) {

    CompletableFuture.runAsync(() -> {
        activity =  LocalTime.now();
    }

    CompletableFuture.runAsync(() -> {
        activity =  LocalTime.now();
    }

    try {
        while (run) {
           Thread.sleep(12000);
           run = false; 
        }
    } catch (InterruptedException e) {
        
    } finally {
        //print activity
    }
}
Run Code Online (Sandbox Code Playgroud)

我正在尝试获得准确的时间。如果我要检查主线程中的活动时间。会准确吗?

编辑:

我现在明白为什么我的代码不是线程安全的。如果我要在同步代码中操作 LocalTime 实例,那会使我的代码线程安全吗?

CompletableFuture.runAsync(() -> {
    synchronized (activity) {
        activity = LocalTime.now();
    }
}       
Run Code Online (Sandbox Code Playgroud)

rzw*_*oot 6

LocalDate 不仅仅是线程安全的。

它是不可变的

线程安全,就类型而言,是指当你改变对象时会发生什么的概念——你总是通过一个点来做到这一点:someExprThatRefersToThatObject.field = foosomeExprThatRefersToThatObject.method()那个方法会导致对象以某种方式改变。

LocalDate 无法实现这些功能。没有修改事物的方法,也没有供您修改的字段。相反,LocalDate 具有根本不修改对象的方法;相反,他们返回新的。例如,someDate.plusDays(1)根本没有改变someDate。它只是返回一个新的LocalDate对象。

这意味着如果您编写类似的代码,并且该代码的线程安全性与 LocalTime 相关,则您的引用会发生变化activity = LocalTime.now();,这一切都与您有关。

具体来说,在您的示例中,这不是线程安全的。它的类型activity是什么并不重要。它可以是int, String, LocalTime, ArrayList, 或其他任何你喜欢的东西:改变一个字段而不与读取它的代码建立先行关系,被破坏了,而您正在这样做。

某些方法可能会规定它们是线程安全的。作为一般规则,尝试在线程之间共享数据比仅仅调用一堆这些方法并祈祷要复杂得多。