简体   繁体   English

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

[英]Getting different output of the same program when written in C# and Java in multithreaded environment

I have a shared boolean static variable uninitialized and created two threads, started one thread, then sleep of two seconds and then started second thread.我有一个未初始化的共享布尔静态变量并创建了两个线程,启动了一个线程,然后休眠了两秒钟,然后启动了第二个线程。

I have print statements basically in both the threads based on the shared variable condition but I am getting different output when ran in c# and java我基本上在基于共享变量条件的两个线程中都有打印语句,但是在 c# 和 java 中运行时我得到了不同的输出

C# code: 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 Code: 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!");
        }
    }
}

In C# whatever number of times I run the code I get both outputs "Hi" and "Hello" but when I run in java only "Hi" gets printed and the programs never terminates(exits).在 C# 中,无论我运行代码多少次,我都会得到输出“Hi”和“Hello”,但是当我在 Java 中运行时,只打印“Hi”并且程序永远不会终止(退出)。 Please explain me the reason of getting different outputs请向我解释获得不同输出的原因

Both programs have multi-threading / concurrency bugs.这两个程序都有多线程/并发错误。 The difference in behavior has to do with details of the underlying implementation of how C# and Java deal with threads, their memory models, how they interact with your hardware, and luck.行为上的差异与 C# 和 Java 如何处理线程的底层实现细节、它们的内存模型、它们如何与您的硬件交互以及运气有关。

Specifically, in both Java and C# - to my knowledge - on a multicore processor, there is no guarantee that one thread sees what the other does unless you have a read memory barrier which you can accomplish either through a synchronized read (which also includes mutual exclusivity and is more expensive, which you do not need here) or a volatile write/read (cheaper and only gives other thread visibility and happens-before guarantees without mutual exclusivity. It's great if you have writers who only write, readers who only read, and if the field you are modifying/reading is an atomic value which is the case in your example).具体来说,在 Java 和 C# 中——据我所知——在多核处理器上,不能保证一个线程看到另一个线程做什么,除非你有一个读取内存屏障,你可以通过同步读取(也包括相互排他性并且更昂贵,您在此处不需要)或易失性写入/读取(更便宜,仅提供其他线程可见性和发生前保证,而没有相互排他性。如果您有只写的作者,只读的读者,那就太好了,并且如果您正在修改/读取的字段是原子值,则在您的示例中就是这种情况)。

Volatile vs. Interlocked vs. lock 易失性 vs. 互锁 vs. 锁定

Happens-before rules in Java Memory Model Java 内存模型中的 Happens-before 规则

guarantee that up-to-date value of variable is always visible to several threads on multi-processor system 保证变量的最新值始终对多处理器系统上的多个线程可见

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM