无法调用线程
Thread can't be called
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 时它不起作用。
有一个有趣的情况,如果我删除评论(System.out.print(“”)),它会起作用。
我可以用另一种方式像回调方法一样,只是我想要的是为什么它不起作用。
简短的版本是,共享变量应该声明为 volatile
或者应该使用适当的同步机制来访问/更新变量。合适的同步机制可以是:
原始监视器的使用;即 synchronized
具有相同目标对象的块或方法。
在同一锁对象上使用 Lock.acquire
和 Lock.release
。
其他 发生在 关系之前。 (不要担心这种情况。它很复杂。但如果你想,请阅读 Java 内存模型。)
无论如何,如果两个线程在没有适当同步的情况下共享一个(非易失性)变量,则不能保证一个线程1看到另一个线程写入的值.这就是您的示例所发生的情况。子线程永远看不到父线程的写入结果。
这是 Java 中多线程的正常行为。 Java 中的并发编程很棘手的原因之一。
1 - 在某些情况下数据会可见,而在其他情况下则不会。它可能取决于 Java 版本、操作系统、硬件平台、是否正在调试以及各种其他因素。可见性问题至少有两个可能的原因。 1)往往是由于内存缓存问题;例如一个线程所做的更改不会被刷新到主内存,以便另一个线程可以看到它们。 2) 或者,它可能(至少在理论上)是由于 JIT 编译器优化了内存提取。要准确了解发生了什么,您需要分析 JIT 编译器发出的本机代码。但无论哪种方式,这些行为都是 Java 内存模型 允许的 ... 如果所需的 在 关系不存在之前发生。
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 时它不起作用。 有一个有趣的情况,如果我删除评论(System.out.print(“”)),它会起作用。 我可以用另一种方式像回调方法一样,只是我想要的是为什么它不起作用。
简短的版本是,共享变量应该声明为 volatile
或者应该使用适当的同步机制来访问/更新变量。合适的同步机制可以是:
原始监视器的使用;即
synchronized
具有相同目标对象的块或方法。在同一锁对象上使用
Lock.acquire
和Lock.release
。其他 发生在 关系之前。 (不要担心这种情况。它很复杂。但如果你想,请阅读 Java 内存模型。)
无论如何,如果两个线程在没有适当同步的情况下共享一个(非易失性)变量,则不能保证一个线程1看到另一个线程写入的值.这就是您的示例所发生的情况。子线程永远看不到父线程的写入结果。
这是 Java 中多线程的正常行为。 Java 中的并发编程很棘手的原因之一。
1 - 在某些情况下数据会可见,而在其他情况下则不会。它可能取决于 Java 版本、操作系统、硬件平台、是否正在调试以及各种其他因素。可见性问题至少有两个可能的原因。 1)往往是由于内存缓存问题;例如一个线程所做的更改不会被刷新到主内存,以便另一个线程可以看到它们。 2) 或者,它可能(至少在理论上)是由于 JIT 编译器优化了内存提取。要准确了解发生了什么,您需要分析 JIT 编译器发出的本机代码。但无论哪种方式,这些行为都是 Java 内存模型 允许的 ... 如果所需的 在 关系不存在之前发生。