我有一个未初始化的共享 boolean 静态变量,并创建了两个线程,启动了一个线程,然后 hibernate 两秒,然后启动了第二个线程。
我基本上在两个线程中都有基于共享变量条件的打印语句,但在 c# 和 java 中运行时得到不同的输出
C# 代码:
class ThreadCache
{
public static bool shared;
public static void Main()
{
new Thread(Meth1).Start();
Thread.Sleep(2000);
new Thread(Meth2).Start();
}
public static void Meth1()
{
while (!shared) { }
Console.WriteLine("Hello");
}
public static void Meth2()
{
shared = true;
Console.WriteLine("Hi");
}
}
Java 代码:
public class HiHello
{
static boolean S1 = false;
public static void main(String[] args) throws InterruptedException {
new Thread(new Thread1(), "Thread 1").start();
Thread.sleep(2000);
new Thread(new Thread2(), "Thread 2").start();
}
private static class Thread1 implements Runnable
{
public void run()
{
while (!HiHello.S1) {}
System.out.println("HELLO!");
}
}
private static class Thread2 implements Runnable
{
public void run()
{
HiHello.S1 = true;
System.out.println("HI!");
}
}
}
在 C# 中,无论我运行代码多少次,我都会得到输出“Hi”和“Hello”,但是当我在 java 中运行时,只会打印“Hi”,并且程序永远不会终止(退出)。请解释一下获得不同输出的原因
最佳答案
两个程序都有多线程/并发错误。行为上的差异与 C# 和 Java 如何处理线程的底层实现细节、它们的内存模型、它们如何与硬件交互以及运气有关。
具体来说,据我所知,在 Java 和 C# 中,在多核处理器上,无法保证一个线程可以看到另一个线程所做的事情,除非您有一个读内存屏障,您可以通过同步读取来完成该屏障(这还包括互斥性并且更昂贵,您在这里不需要)或 volatile 写/读(更便宜并且只提供其他线程可见性和发生之前保证而没有互斥性。如果您有只写的写入者,读者,那就太好了谁只读取,以及您正在修改/读取的字段是否是原子值(您的示例中就是这种情况)。Volatile vs. Interlocked vs. lock
关于java - 在多线程环境中用 C# 和 Java 编写同一程序时获得不同的输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56609872/