一道有意思的多線程面試題 C# 代碼實現


 

如果你對多線程的控制不怎么了解,那么理解了這篇文章的內容也許對你有幫助。鼓勵先自己動手實現一遍,做不出來在看代碼。

 

題目一:兩個線程交替打印0~100的奇偶數

這道題就是說有兩個線程,一個名為偶數線程,一個名為奇數線程,偶數線程只打印偶數,奇數線程只打印奇數,兩個線程按順序交替打印。本文重點不是說的這道題,這道題是下面那道題的簡單版本,用來做個過渡。

效果圖:

此題核心點就是如何控制多線程的執行順序,我們知道C#的System.Threading命名空間給開發者提供了控制線程相關的對象,線程同步常用對象有:Semaphore,ManualResetEvent,AutoResetEvent,這里我用AutoResetEvent來實現,代碼如下:

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

我這里是兩個線程調用不同的方法實現,可讀性會好點,如果只調用一個同樣的方法你們會怎么實現呢?

題目二:通過N個線程順序循環打印0~100

這篇文章主要是說這道題,此題據稱是阿里的面試題,具體效果如下:

通過N個線程順序循環打印從0至100,如給定N=3則輸出: 

 這個題開始真沒想出來,后來無意在github上有人用Java做出了答案,看到使用了Semaphore去控制,我就用C#代碼做了下,代碼如下:

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[n] };
        for (var i = 0; i < n; i++)
        {
            work.Semaphores[i] = new Semaphore(1, 1);
            if (i != n - 1)
                work.Semaphores[i].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.Length - 1] : Semaphores[i - 1];
        var curSemaphore = Semaphores[i];
        while (true)
        {
            preSemaphore.WaitOne();
            Interlocked.Increment(ref index);
            if (index > 99)
                return;
            Console.WriteLine($"{Thread.CurrentThread.Name}:{index}");
            curSemaphore.Release();
        }
    }
}
View Code

 

如果現實面試我第一次碰上了這樣的題目,估計是答不上來了,那么你們覺得出這樣難度面試題的公司月薪給多少K合適?

完整代碼:https://github.com/Ax0ne/Example.Leetcode/blob/master/src/Example.Leetcode/Problems/ThreadExample.cs  歡迎star喲,后面會陸續添加一些有意思的題目代碼。

博友們還能有不同的實現方式嗎 ? ^_^


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM