我在代码下面运行:
import java.util.*;
public class Common_variable extends Thread{
private boolean running = true;
public void run()
{
while(running)
{
try {
System.out.println("Hello");
Thread.sleep(100);
} catch (InterruptedException ex) {
System.out.println(ex);
}
}
}
public void shutdown()
{
running = false;
}
}
public class Thread_demo{
public static void main(String args[])
{
Common_variable x = new Common_variable();
x.start();
Scanner in = new Scanner(System.in);
in.nextLine();
x.shutdown();
}
}
现在,我有一些疑问。 当我们做" Common_variable x = new Common_variable();"时,创建新线程,这意味着单独的堆栈。那时,一个对象x也在堆中创建。我怀疑是:
是否只有#34;运行"的单一副本变量或新线程在其堆栈中也有一个?如果是,则两个线程如何能够相互通信并更新"运行"。如果没有,并且两者都从相同的内存位置访问,那么如果我们将变量运行为volatile,则会有什么不同。
请澄清我的理解错误。
答案 0 :(得分:2)
这与线程堆栈无关。 running
是对象的字段,因此存储在堆中。
但是由于多核计算机上的性能优化,每个核心都可以在其缓存中拥有此值的副本:访问缓存比访问主内存更快。
没有volatile,当主线程将标志设置为false时,无法保证其他线程会看到该更改:缓存的值不会被写入主内存,并且线程赢了&# 39;从主存储器重新读取它。
volatile
保证对变量的每次更改都写入主内存,并且在该更改之后每次读取变量都会从主内存中重新读取。
那就是说,你应该优先选择AtomicBoolean而不是volatile变量。在这种情况下,您甚至根本不需要变量:每个线程都有一个中断标志,您可以通过interrupting the thread进行更改。这种内在机制的优点是,一旦线程被中断,线程就不会保持睡眠状态:它会立即退出sleep()方法,抛出InterruptedException,这将允许你立即停止线程。
答案 1 :(得分:1)
当我们做“Common_variable x = new Common_variable();”
时
不,当您拨打start()
时会创建单独的堆栈。
您只创建了一个Common_variable
对象,并且它有一个名为running
的实例变量,因此如果您将此对象传递给各个线程,它们将共享running
实例变量,可能会导致数据损坏,这就是我们使用同步来防止数据损坏的原因。
至于volatile,它保证了线程变量变化的可见性
请阅读此内容以获取更多http://tutorials.jenkov.com/java-concurrency/volatile.html