“局部变量是线程安全的”是否带有条件?

时间:2017-11-12 03:47:54

标签: java multithreading

在另一个主题中,我遇到了这个问题,所以我必须把它放在这里作为一个简单而专注的问题。

void method(){

   Machine machine = new Machine();
   ...
}

class Machine{
   private static Tool tool = new Tool();    
   ...
}

虽然Machine是method()中的局部变量,但它仍然是不安全的线程,因为Machine有一个静态的实例变量'tool'可能是线程不安全的,因为所有线程都会因静态而共享这个'tool'对象。

因此,如果Machine通过任何方式本身都是线程安全的,那么可以安全地声明“本地变量机器”是线程安全的。否则,即使“机器”是局部变量,它也不安全。

这种理解是否正确?

3 个答案:

答案 0 :(得分:3)

是的,语句局部变量是线程安全的有几个条件。

首先,让我们看看为什么局部变量是线程安全的。这是因为变量是在方法自己的堆栈帧上分配的,不与任何其他执行路径共享。

因此,重要的是要注意变量本身是线程安全的,不一定是它所指向的。换句话说:

  • 原始变量完全是线程安全的,因为值在堆栈本身上
  • 对象引用是一个更复杂的故事,因为实际对象是在堆上创建的,而堆栈框架只是指向堆内存。

在下图中,整数变量是线程安全的,但Object和Array不是。 enter image description here

对象是否完全是线程安全的,取决于该类是否设计为线程安全的。

答案 1 :(得分:2)

是的,这种理解是正确的。只有变量本身是线程安全的,因为其他线程不会同时修改它的值。

此保护不会扩展到本地变量引用的对象:取决于对象的内部构造,例如可变性和静态变量的使用,该对象可能是也可能不是线程安全的。

请注意,原始类型的局部变量和引用不可变对象的局部变量始终是线程安全的。

答案 2 :(得分:1)

  

因此,如果Machine通过任何方式本身都是线程安全的,那么可以安全地声明"本地变量机器"是线程安全的。

可以始终无条件地声明本地变量machine'它是线程安全的,无论它引用的任何对象的线程安全性如何。

  

否则,它不安全,即使机器'是一个局部变量。

如果'它'指的是局部变量,它始终是线程安全的。

  

这种理解是否正确?

没有。您将变量与对象混淆。

  • 本地变量(例如示例中的machine)是线程安全的句点。
  • 对象是否是线程安全的,具体取决于它们内部的内容,对它们被引用的位置和方式的重新定义,即在这种情况下,对象是否是一个实例Machine的{​​{1}}由本地变量machine引用。