如果多个线程读取先前已设置且之后不会更改的基本类型,它们是否会得到错误的值?
例如,假设以下简单代码摘录:
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,那么之后访问它应该始终是线程安全的,是否正确?
答案 0 :(得分:1)
由于proceed
是static
和final
,因此无法重新分配,这会转为线程安全。
static
表示它是类级别,而final
表示它的值无法更改,这是一个primitive
如此挑衅,这是不可变的,因此是线程安全的。
答案 1 :(得分:1)
您的变量为final
这一事实可确保所有线程都能在一致的后初始化状态下看到它。这也适用于对象的引用(即,如果已初始化为非空引用,则所有线程都将看到Object的非null值 - 但如果您的对象不是线程安全的,则某些线程可能会看到对象本身在不一致或陈旧的状态。)
ps:假设你的read方法没有尝试读取布尔值,在这种情况下它会看到默认(false)值。
答案 2 :(得分:1)
你说它是不可变的(static and final)
,所以我们可以肯定地说它是线程安全的。
答案 3 :(得分:1)
引用是线程安全的,因为它是不可变的。
如果它是可变的,您需要使用volatile
关键字以确保在另一个线程中修改后获得最新值。