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

摘要:
主题2:按顺序打印0~100到N个线程。本文主要是关于这个问题。这个问题据说是阿里的采访问题。具体效果如下:依次打印0到100到N个线程。如果N=3,则结果是:这个问题最初真的没有被考虑过。后来,github上有人无意中用Java给出了答案。当我看到Semaphore被用来控制它时,我用C#代码进行了处理,代码如下:publicclassThreadExample{//////N个线程从0到100///////<paramname=“N”˃publicstaticvoidPrintNumber{varwork=newTheadWorkTest{Semaphores=newSemaphore[N]};对于{work.Photos[i]=newSemaphore(1,1);如果(i)完整代码:https://github.com/Ax0ne/Example.Leetcode/blob/master/src/Example.Leetcode/Problems/ThreadExample.cs欢迎来到明星。稍后将添加一些有趣的标题代码。博主们能有不同的方式来实现这一点吗?

如果你对多线程的控制不怎么了解,那么理解了这篇文章的内容也许对你有帮助。鼓励先自己动手实现一遍,做不出来在看代码。

题目一:两个线程交替打印0~100的奇偶数

这道题就是说有两个线程,一个名为偶数线程,一个名为奇数线程,偶数线程只打印偶数,奇数线程只打印奇数,两个线程按顺序交替打印。本文重点不是说的这道题,这道题是下面那道题的简单版本,用来做个过渡。

效果图:

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

此题核心点就是如何控制多线程的执行顺序,我们知道C#的System.Threading命名空间给开发者提供了控制线程相关的对象,线程同步常用对象有:Semaphore,ManualResetEvent,AutoResetEvent,这里我用AutoResetEvent来实现,代码如下:

一道有意思的多线程面试题 C# 代码实现第2张一道有意思的多线程面试题 C# 代码实现第3张
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则输出:
一道有意思的多线程面试题 C# 代码实现第4张

 这个题开始真没想出来,后来无意在github上有人用Java做出了答案,看到使用了Semaphore去控制,我就用C#代码做了下,代码如下:

一道有意思的多线程面试题 C# 代码实现第5张一道有意思的多线程面试题 C# 代码实现第6张
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哟,后面会陆续添加一些有意思的题目代码。

博友们还能有不同的实现方式吗 ? ^_^

免责声明:文章转载自《一道有意思的多线程面试题 C# 代码实现》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇word导出失败问题rpm包管理工具下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

iOS-消息循环RunLoop详解

RunLoop,跑圈。在iOS开发中,也就是运行循环。 在应用需要的时候自己跑起来运行,在用户没有操作的时候就停下来休息。充分节省CPU资源,提高程序性能。 二. RunLoop的概念与作用 概念:一般来讲,一个线程一次只能执行一个任务,执行完成后线程就会退出。但是有时候我们需要线程能够一直“待命”随时处理事件而不退出,这就需要一个机制来完成这样的...

Java 并发系列之七:java 阻塞队列(7个)

1.基本概念 2.实现原理 3.ArrayBlockingQueue 4.LinkedBlockingQueue 5.LinkedBlockingDeque 6.PriorityBlockingQueue 7.DelayQueue 8.SynchronousQueue 9.LinkedTransferQueue 10.小总结 11.t...

js与Nodejs的单线程和异步--初探

Event Loop Event Loop : 浏览器使用 Event Loop 来协调 DOM 事件、UI 渲染、脚本执行和网络事件等。 Task Queue (Event Queue) :每当 DOM 事件、计时器事件或者网络事件被触发时,它们的回调函数和 Context 都会被压入 Event Queue,而 Event Loop 则会从中取出...

WPF 同一窗口内的多线程 UI(VisualTarget)

WPF 的 UI 逻辑只在同一个线程中,这是学习 WPF 开发中大家几乎都会学习到的经验。如果希望做不同线程的 UI,大家也会想到使用另一个窗口来实现,让每个窗口拥有自己的 UI 线程。然而,就不能让同一个窗口内部使用多个 UI 线程吗? 答案其实是——可以的!使用 VisualTarget 即可。 阅读本文将收获一份对 VisualTarget 的解读以...

多线程编程5种方法实现线程同步

1:用Interlocked系列函数实现线程同步; 2:用CRITICAL_SECTION及其系列函数实现线程同步; 3:用RTL_SRWLOCK及其系列函数实现线程同步; 4:用事件内核对象实现线程同步; 5:用信号量内核对象实现线程同步;   1:用Interlocked系列函数实现线程同步实例如下: //旋转锁 #include <iostre...

ios 多线程

转自:http://www.maxiaoguo.com/clothes/254.html 多线程包含:GCD  NSOperation   NSOperation是在GCD语言的基础上开发的,GCD类C语言, NSOperation OC语法 GCD: 名词解释  并行 dispatch_queue_t q = dispatch_queue_crea...