0

如果多个线程读取先前设置的原始类型并且以后不会更改,它们会得到错误的值吗?

例如,假设以下简单代码摘录:

public static final boolean proceed = read(); // Read the value from a file

public static void doSomething() // Method accessed by multiple threads
{
    if (proceed)
    {
        System.out.println("TRUE");
    }
    else
    {
        System.out.println("FALSE");
    }
}

假设proceed变量被初始化为true,是否有可能在同时运行该doSomething()方法的多个线程中的一个或多个线程中,打印的消息是FALSE

如果proceed变量是可变的,那肯定是可能的,因此需要同步或使用AtomicBoolean(例如,根据这个问题)。但在这种情况下,proceed它是不可变的,并且只在包含类的静态初始化期间设置一次。

类似地,对于其他原始类型,如果一个值设置为 final,那么以后访问它应该始终是线程安全的,对吗?

4

4 回答 4

1

由于proceedisstaticfinal,它不能被重新分配,这变成了线程安全的。

static说它是类级别的,并final说它的值不能改变,这是一个primitive如此挑衅的不可变的,因此是线程安全的。

于 2012-07-18T13:16:18.187 回答
1

您的变量是final保证所有线程将在一致的初始化后状态中看到它的事实。这也适用于对象的引用(即,如果对象已被初始化为非空引用,则所有线程都将看到该对象的非空值 - 但如果您的对象不是线程安全的,则某些线程可能会在不一致或陈旧的状态)。

ps:假设您的 read 方法不尝试读取布尔值,在这种情况下它将看到默认(false)值。

于 2012-07-18T13:16:39.170 回答
1

你说它是不可变(static and final)的,所以我们可以有把握地说它是线程安全的。

于 2012-07-18T13:17:08.057 回答
1

引用是线程安全的,因为它是不可变的。

如果它是可变的,则需要使用volatile关键字来确保在另一个线程中修改时获得最新值。

你曾经在 Java 中使用过 volatile 关键字吗?

于 2012-07-18T13:17:54.373 回答