ibcadmin 发表于 2019-8-15 11:40:02

一道有意思的多线程面试题 C# 代码实现

<p>文章转载自:http://www.pythonheidong.com/blog/article/2553/</p>
<p> </p>
<p><strong>如果你对多线程的控制不怎么了解,那么理解了这篇文章的内容也许对你有帮助。鼓励先自己动手实现一遍,做不出来在看代码。</strong></p>
<p> </p>
<h1>题目一:两个线程交替打印0~100的奇偶数</h1>
<p>这道题就是说有两个线程,一个名为偶数线程,一个名为奇数线程,偶数线程只打印偶数,奇数线程只打印奇数,两个线程按顺序交替打印。<strong>本文重点不是说的这道题,这道题是下面那道题的简单版本,用来做个过渡。</strong></p>
<p>效果图:</p>
<p><div align="center"></div></p>
<p>此题焦点点就是如何控制多线程的执行顺序,我们知道C#的System.Threading命名空间给开发者提供了控制线程相关的对象,线程同步常用对象有:Semaphore,ManualResetEvent,AutoResetEvent,这里我用AutoResetEvent来实现,代码如下:</p>
<div align="center"></div><div align="center"></div>

public class ThreadExample
{
    /// <summary>
    /// 两个线程交替打印0~100的奇偶数
    /// </summary>
    public static void PrintOddEvenNumber()
    {
      var work = new TheadWorkTest();
      var thread1 = new Thread(work.PrintOddNumer) { Name = "奇数线程" };
      var thread2 = new Thread(work.PrintEvenNumber) { Name = "偶数线程" };
      thread1.Start();
      thread2.Start();
    }
}

public class TheadWorkTest
{
    private static readonly AutoResetEvent oddAre = new AutoResetEvent(false);
    private static readonly AutoResetEvent evenAre = new AutoResetEvent(false);

    public void PrintOddNumer()
    {
      oddAre.WaitOne();
      for (var i = 0; i < 100; i++)
      {
            if (i % 2 != 1) continue;
            Console.WriteLine($"{Thread.CurrentThread.Name}:{i}");
            evenAre.Set();
            oddAre.WaitOne();
      }
    }

    public void PrintEvenNumber()
    {
      for (var i = 0; i < 100; i++)
      {
            if (i % 2 != 0) continue;
            Console.WriteLine($"{Thread.CurrentThread.Name}:{i}");
            oddAre.Set();
            evenAre.WaitOne();
      }
    }
}

View Code
<p>我这里是两个线程调用不同的方法实现,可读性会好点,如果只调用一个同样的方法你们会怎么实现呢?</p>
<h1>题目二:通过N个线程顺序循环打印0~100</h1>
<p>这篇文章主要是说这道题,此题据称是阿里的面试题,具体效果如下:</p>
<code>通过N个线程顺序循环打印从0至100,如给定N=3则输出:
<div align="center"></div><br></code>
<p> 这个题开始真没想出来,后来无意在github上有人用Java做出了答案,看到使用了Semaphore去控制,我就用C#代码做了下,代码如下:</p>
<div align="center"></div><div align="center"></div>

public class ThreadExample
{

    /// <summary>
    /// N个线程顺序循环打印从0至100
    /// </summary>
    /// <param name="n"></param>
    public static void PrintNumber(int n = 3)
    {
      var work = new TheadWorkTest { Semaphores = new Semaphore };
      for (var i = 0; i < n; i++)
      {
            work.Semaphores = new Semaphore(1, 1);
            if (i != n - 1)
                work.Semaphores.WaitOne();
      }
      for (var i = 0; i < n; i++)
      {
            new Thread(work.PrintNumber) { Name = "线程" + i }.Start(i);
      }
    }
}

public class TheadWorkTest
{
    public Semaphore[] Semaphores { get; set; }
    public static int index;
    public void PrintNumber(object c)
    {
      var i = Convert.ToInt32(c);
      var preSemaphore = i == 0 ? Semaphores : Semaphores;
      var curSemaphore = Semaphores;
      while (true)
      {
            preSemaphore.WaitOne();
            Interlocked.Increment(ref index);
            if (index > 99)
                return;
            Console.WriteLine($"{Thread.CurrentThread.Name}:{index}");
            curSemaphore.Release();
      }
    }
}

View Code
<p> </p>
<p>如果现实面试我第一次碰上了这样的题目,估计是答不上来了,那么你们以为出这样难度面试题的公司月薪给多少K符合?</p>
<p>完整代码:https://github.com/Ax0ne/Example.Leetcode/blob/master/src/Example.Leetcode/Problems/ThreadExample.cs欢迎star哟,后面会陆续添加一些有意思的题目代码。</p>
<p>博友们还能有不同的实现方式吗 ? ^_^</p>

<p>文章转载自:http://www.pythonheidong.com/blog/article/2553/</p><br>来源:<a href="https://www.cnblogs.com/xiongbatianxiaskjdskjdksjdskdtuti/p/11356741.html" target="_blank">https://www.cnblogs.com/xiongbatianxiaskjdskjdksjdskdtuti/p/11356741.html</a>
页: [1]
查看完整版本: 一道有意思的多线程面试题 C# 代码实现