class client
{
static int data = 0;
public static void main(String[] args)
{
new Thread(new Runnable()
{
@Override
public void run()
{
while(true)
{
//System.out.print("");
if(data == 1) {System.out.println("GOTCHA");}
}
}
}).start();
Scanner sc = new Scanner(System.in);
while(true)
{
data = sc.nextInt();
}
}
}
我不明白为什么输入1时它不起作用。并且有一种有趣的情况,如果我删除comment(System.out.print(“”)),它会起作用。我可以像回调方法那样用另一种方式,只是我想要的是为什么它不起作用。
简短的版本是共享变量应声明为volatile
,或者使用适当的同步机制对变量进行访问/更新。适当的同步机制可以是:
使用原始监视器;即synchronized
具有相同目标对象的块或方法。
在同一锁定对象上使用Lock.acquire
和Lock.release
。
具有适当的在……之前]关系的其他东西。 (不必担心这种情况。它很复杂。但是,如果您愿意,请阅读Java内存模型。)
无论如何,如果两个线程共享一个(非易失性)变量而没有适当的同步,则不能保证一个线程1
这是Java中多线程的正常行为。这也是Java并发编程之所以棘手的原因之一。
1-在某些情况下,数据将可见,在其他情况下则将不会。它可能取决于Java版本,操作系统,硬件平台,是否要调试以及其他各种情况。可见性问题至少有两个可能的原因。 1)这通常是由于内存缓存问题引起的;例如一个线程所做的更改未刷新到主内存,以便另一线程可以看到它们。 2)或者,至少在理论上,这可能是由于JIT编译器优化了内存获取。要确切了解发生了什么,您需要分析JIT编译器发出的本机代码。但是无论哪种方式,Java内存模型都将这些行为permitted
...如果不存在所需的happens before关系。简短的版本是,共享变量应声明为volatile
,或者使用适当的同步机制对变量进行访问/更新。适当的同步机制可以是:
使用原始监视器;即synchronized
具有相同目标对象的块或方法。
在同一锁定对象上使用Lock.acquire
和Lock.release
。
具有适当的在……之前]关系的其他东西。 (不必担心这种情况。它很复杂。但是,如果您愿意,请阅读Java内存模型。)
无论如何,如果两个线程共享一个(非易失性)变量而没有适当的同步,则不能保证一个线程1
这是Java中多线程的正常行为。这也是Java并发编程之所以棘手的原因之一。
1-在某些情况下,数据将可见,在其他情况下则将不会。它可能取决于Java版本,操作系统,硬件平台,是否在调试以及其他各种情况。