多个线程读取基本类型

时间:2012-07-18 13:12:42

标签: java thread-safety primitive

如果多个线程读取先前已设置且之后不会更改的基本类型,它们是否会得到错误的值?

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

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()方法的多个线程中的一个或多个线程中,打印的消息为{ {1}}?

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

对于其他原始类型,如果将一个值设置为final,那么之后访问它应该始终是线程安全的,是否正确?

4 个答案:

答案 0 :(得分:1)

由于proceedstaticfinal,因此无法重新分配,这会转为线程安全。

static表示它是类级别,而final表示它的值无法更改,这是一个primitive如此挑衅,这是不可变的,因此是线程安全的。

答案 1 :(得分:1)

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

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

答案 2 :(得分:1)

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

答案 3 :(得分:1)

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

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

Do you ever use the volatile keyword in Java?