gpt4 book ai didi

java - 在多线程环境中用 C# 和 Java 编写同一程序时获得不同的输出

转载 作者:行者123 更新时间:2023-11-30 05:36:00 25 4
gpt4 key购买 nike

我有一个未初始化的共享 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

Happens-before rules in Java Memory Model

guarantee that up-to-date value of variable is always visible to several threads on multi-processor system

关于java - 在多线程环境中用 C# 和 Java 编写同一程序时获得不同的输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56609872/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com