在线程中观察不同的输出

时间:2014-08-25 12:05:04

标签: c# asp.net .net multithreading

我在探索线程概念, 每次当我尝试执行以下代码时,我都会得到不同的输出。 我首先启动ThreadOne,但为什么ThreadTwo开始了。 为什么我得到不同的输出?有人能解释一下吗? 在此先感谢。

static Object newLockobj = new Object();
    static void Main(string[] args)
    {
        Thread tobj1 = new Thread(ThreadOne);
        Thread tobj2 = new Thread(ThreadTwo);
        tobj1.Start();
        tobj2.Start();

        Console.ReadLine();
    }

    static void ThreadOne()
    {
        Console.WriteLine("Thread One Entered");
        lock (newLockobj)
        {
            Console.WriteLine("Thread 1 started");
            Thread.Sleep(2000);
            Console.WriteLine("Thread 1 ended");
        }
    }

    static void ThreadTwo()
    {
        Console.WriteLine("Thread Two Entered");
        lock (newLockobj)
        {
            Console.WriteLine("Thread 2 started");
            Thread.Sleep(1000);
            Console.WriteLine("Thread 2 ended");
        }
    }

Observed Output

2 个答案:

答案 0 :(得分:3)

这是并发的基本考试。一旦在线程对象上调用.Start()方法,它就会独立于启动它的线程开始执行。您的计划正在做什么:

  1. 创建线程对象
  2. 启动tobj1(线程不会直接执行,但一旦调度程序找到放置它的位置)
  3. 启动tobj2(线程再次不直接执行)
  4. scheduler负责告诉处理器执行哪个进程和哪个线程。线程的启动顺序并不重要。

    一旦一个线程启动,他就会打印第一行(“Thread X Entered”)。 Lock是一个同步语句。由于两个线程在同一个对象实例上同步,因此无法同时进入锁定块(Mutual Exclusion)。 Lock语句仅确保进程可以在关键部分中工作,而其他进程不会在其关键部分工作。正如您在右侧输出中看到的那样,虽然线程处于关键部分(“线程2已启动”,“已进入线程1”,“......”),但线程可能会被中断。但是,“Thread One”不允许进入他的关键部分,因为其他线程尚未释放锁定。

答案 1 :(得分:1)

这是线程编程的核心。虽然您可以控制首先启动哪个线程,但CPU没有义务遵循您的事件顺序。在执行一个线程期间,CPU保证按照您的编程顺序执行代码执行。在调度不同的线程时,CPU将遵循自己的逻辑,有时逻辑看起来像随机行为。它会根据需要将处理时间分配给不同的线程。

我建议你阅读更多关于线程编程的内容,因为没有完全理解这个概念,并且认识到它的潜在缺陷会导致很多天的拔毛和可能的死锁:)

只是google:c#threading。你会得到很多好资源!