如果你對多線程的控制不怎麼瞭解,那麼理解了這篇文章的內容也許對你有幫助。鼓勵先自己動手實現一遍,做不出來在看代碼。 題目一:兩個線程交替列印0~100的奇偶數 這道題就是說有兩個線程,一個名為偶數線程,一個名為奇數線程,偶數線程只列印偶數,奇數線程只列印奇數,兩個線程按順序交替列印。本文重點不是說的 ...
如果你對多線程的控制不怎麼瞭解,那麼理解了這篇文章的內容也許對你有幫助。鼓勵先自己動手實現一遍,做不出來在看代碼。
題目一:兩個線程交替列印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喲,後面會陸續添加一些有意思的題目代碼。
博友們還能有不同的實現方式嗎 ? ^_^