面试官您好,我是来面试的

您好,我是这次的面试官,先介绍一下自己把

我是女孩,blala ....

那问一个多线程的问题吧,在一个多线程的环境中,怎么能保证一系列方法的执行顺序呢?

01

PART

题目

比如我们有三个方法,类似以下代码

static void Methond1(){Console.WriteLine($"{Thread.CurrentThread.Name} 执行 第一个方法==");}static void Methond2(){Console.WriteLine($"{Thread.CurrentThread.Name} 执行 第二个方法=======");}static void Methond3(){Console.WriteLine($"{Thread.CurrentThread.Name} 执行  第三个方法=======");}}

分别初始化三个线程去执行这三个方法,每个线程执行的方法可以任意指定,但是方法的执行顺序必须是:Methond1=》Methond2=》Methond3

示例:

输入:3,2,1  
第一个线程执行方法3,第二个线程执行方法2,第三个线程执行方法1
输出:Methond1的输出=》Methond2的输出=》Methond3 的输出 ,即:
xxx执行 第一个方法==
xxx执行 第二个方法==
xxx执行 第三个方法==

面试官大哥,我好像不会哦

没关系,留下你的联系方式,如果可以,我们会有后续人员联系你的,感谢你来面试

02

PART

题解分析

这道题本质上考的是多线程环境资源竞争的问题,在多线程环境下要想以固定某个顺序执行方法,必须要有一个类似屏障的东西来阻止不该执行的线程,或者换句话说必须要有一个机制来顺序化多个线程。这也是我们平时多线程开发环境中必须要面对的问题,现代服务器的cpu都是多核心,我们平时用的最多的java,c#等高级语言是能够利用服务器多核心这个优势的,这里是一个进程内,多线程就可以利用多核心。当然也有一些别的技术,比如Nodejs,虽然执行是单线程的,但是可以利用多进程来提高多物理cpu的利用率。

说的有点远了,接下来还是看这道题,这道题目考验的是多线程下资源的竞争问题和线程间的通信问题,说的直白一点就是:Methond1未执行之前,任何方法都不能执行(这里是指方法内的代码),Methond1执行完之后,会通知执行Methond2的线程,Methond2开始执行,Methond2执行完毕会通知执行Methond3的线程,以此类推。所以这道题的关键在于阻塞某个线程执行和通知某个线程执行。

在很多语言中都提供了lock的机制,或者信号量的机制。这些都是可以实现线程间通信的的解决方案,当然最简单暴力的方式还是通过共享变量的方式来实现通知,虽然有很多缺陷,但是在很多情况下确实是最简单快捷的方案。下边就以c#语言为例:

class Program{//把三个方法分别对应到 委托,为了方便执行方法static Action FirstAction = Methond1;static Action SecondAction = Methond2;static Action ThirdAction = Methond3;static Dictionary<int, Action> ActionDic = new Dictionary<int, Action>() { { 1, FirstAction }, { 2, SecondAction }, { 3, ThirdAction } };static void Main(string[] args){while (true){Console.WriteLine("请输入顺序");var inputStr = Console.ReadLine();IsFinish1 = IsFinish2 = false;var input = inputStr.Split(",").Select(s => int.Parse(s));foreach (var i in input){var method = ActionDic.GetValueOrDefault(i);Thread t = new Thread(method.Invoke);t.Name = "线程" + i;Console.WriteLine($"{t.Name} 执行方法 {method.Method.Name}");t.Start();}}}static object objLock = new object();static bool IsFinish1 = false; //第一方法是否执行完毕static bool IsFinish2 = false; //第二方法是否执行完毕static void Methond1(){Console.WriteLine($"{Thread.CurrentThread.Name} 执行 第一个方法==");IsFinish1 = true;}static void Methond2(){while (true){if (IsFinish1){Console.WriteLine($"{Thread.CurrentThread.Name} 执行 第二个方法=======");IsFinish2 = true;break;}}}static void Methond3(){while (true){if (IsFinish2){Console.WriteLine($"{Thread.CurrentThread.Name} 执行  第三个方法=======");break;}}}}

测试执行:

请输入顺序
2,3,1
线程2 执行方法 Methond2
线程3 执行方法 Methond3
线程1 执行方法 Methond1
请输入顺序
线程1 执行 第一个方法==
线程2 执行 第二个方法=======
线程3 执行  第三个方法=======
3,2,1
线程3 执行方法 Methond3
线程2 执行方法 Methond2
线程1 执行方法 Methond1
请输入顺序
线程1 执行 第一个方法==
线程2 执行 第二个方法=======
线程3 执行  第三个方法=======

不要太纠结以上的代码,以上只是作为抛砖引玉的作用,就算是有执行错误,思路我觉得还是没有问题的,当然确实有很多要优化的地方,比如等待执行的线程一直在耗费cpu资源的情况,可以替换为自旋锁或者混合锁,有兴趣的同学可以进行优化一番。

03

PART

公司简介

但是,作为语法很优秀的c#怎么能就此止步呢?c#本身提供了Task的机制,可以把它看做是类似golang的协程(虽然不是很像)。基于task的机制我们很容易就完成,task的 ContinueWith机制就是为此而生的,它可以很方便的把多个并行的task串行化,有兴趣的同学可以试一下,但是我要说的并非ContinueWith。既然要执行的顺序化,如果我把执行的代码放在有顺序的容器中,然后按照顺序去执行,岂不快哉?不多废话:

class TaskTest{static Func<Task> FirstAction = Methond1;static Func<Task> SecondAction = Methond2;static Func<Task> ThirdAction = Methond3;static Dictionary<int, Func<Task>> ActionDic = new Dictionary<int, Func<Task>>() { { 1, FirstAction }, { 2, SecondAction }, { 3, ThirdAction } };static Func<Task>[] tList = new Func<Task>[3];public static void Start(){while (true){Console.WriteLine("请输入顺序");var inputStr = Console.ReadLine();var input = inputStr.Split(",").Select(s => int.Parse(s));foreach (var i in input){var method = ActionDic.GetValueOrDefault(i);tList[i-1] = method;}foreach (var t in tList){t.Invoke().Wait();}}}static Task Methond1(){return Task.Run(()=> {Console.WriteLine($"{Thread.CurrentThread.Name} 执行 第一个方法==");});}static Task Methond2(){return  Task.Run(() => {Console.WriteLine($"{Thread.CurrentThread.Name} 执行 第二个方法=======");});}static Task Methond3(){return Task.Run(() => {Console.WriteLine($"{Thread.CurrentThread.Name} 执行  第三个方法=======");});}}

测试:

请输入顺序
2,3,1
执行 第一个方法==
执行 第二个方法=======
执行  第三个方法=======
请输入顺序
3,2,1
执行 第一个方法==
执行 第二个方法=======
执行  第三个方法=======
请输入顺序
1,3,2
执行 第一个方法==
执行 第二个方法=======
执行  第三个方法=======
请输入顺序

是不是很爽,毫不犹豫的说c#是一门很优秀的语言,在并发方面做的很优秀。以上Task的代码并非是最优代码,比如 可以用Await来代替 wait(),这样的话在真实环境中可以释放当前线程来提高吞吐量,记住:await方式提高的吞吐量,并非缩短了单次请求的执行时间。

助你早日进入谷歌!!!

特别推荐一个分享架构+算法的优质内容,还没关注的小伙伴,可以长按关注一下:长按订阅更多精彩▼如有收获,点个在看,诚挚感谢

进击谷歌:多线程下程序执行顺序怎么稳定不乱?相关推荐

  1. 学习MFC首先要知道的--程序执行顺序

    MFC的程序执行顺序 很多刚学MFC的人都会被MFC给弄的晕头转向.以前传统的C语言中的main()不见了,window sdk api 中的WinMain()函数也不见了,到底用MFC编写的程序是如 ...

  2. GO函数内部程序执行顺序

    目录 GO 包 标准库 程序执行顺序 GO 包 包是结构化代码的一种方式:每个程序都由包(通常简称为pkg)的概念组成,可以使用自身的包或者从其它包中 导入内容. 如同其它一些编程语 言中的类库或命名 ...

  3. Java实例化后自动执行_Java的实例化顺序(程序执行顺序)

    加载/执行顺序: 牢记一点: 静态和非静态分开处理 使用到静态加载时,静态又分为: 静态变量, 静态代码块, 其中加载顺序是按照类中书写的先后顺序加载的 非静态加载顺序: 按照非静态书写顺序加载/执行 ...

  4. UIViewController的生命周期及iOS程序执行顺序

    当一个视图控制器被创建,并在屏幕上显示的时候. 代码的执行顺序 1. alloc                                   创建对象,分配空间 2.init (initWit ...

  5. Python程序执行顺序

    #示例代码基于py3.6 一直对Python程序的执行顺序有些疑惑,例如python程序是顺序执行的,那怎么还有main函数的出现呢? 在查阅了资料后,参见这里后,算是有点明白了: 1.python程 ...

  6. linux下程序执行的步骤及其作用

    程序执行的步骤及其作用 在linux下使用gcc编程时,从表面上看是简单的命令的执行,但实际上,程序的执行分为四个步骤:预编译,编译,汇编,链接. 预编译 在linux系统下,一个.c文件经过预编译生 ...

  7. java中子类继承父类程序执行顺序问题

    为什么80%的码农都做不了架构师?>>>    Java中,new一个类的对象,类里面的静态代码块.非静态代码.无参构造方法.有参构造方法.类的一般方法等部分,它们的执行顺序相对来说 ...

  8. python导包顺序_2019-03-21 python导入包以及Python程序执行顺序理解

    http://codingpy.com/article/python-import-101/ https://segmentfault.com/a/1190000009842139 (一)Python ...

  9. python多个for的执行顺序-python_装饰器篇(多个装饰器下的执行顺序)

    在之前的帖子中,简单自我总结了装饰器的几个情况以及基本上使用,那么有基本上说的都是单个的装饰器修饰方法 有时候我们会发现一个方法上面有多个装饰器 如下: @dec2 @dec def a(a): if ...

最新文章

  1. 计算机游戏88关,天天象棋88关怎么过 闯关模式第88关图文攻略
  2. MyBatis 实际使用案例-typeHandlers【重点】
  3. linux怎样测试tty,linux – 提示自定义:如何检测何时没有tty
  4. fatal: unable to access ‘https://github.comxxxxxxxxxxx‘: Failed to connect to xxxxxxxxxxxxx
  5. Maven 依赖-镜像仓库替换为 -- 阿里云镜像仓库(飞快实现 pom 引入)
  6. day37-数据库分组查询
  7. python列表切片图解_Python列表切片操作实例总结
  8. node.js express架构安装部署
  9. idea 跳转到行数,Intellij IDEA 一些不为人知的技巧
  10. wordpress 后台404解决办法
  11. nginx做代理上网
  12. 谷歌收购DNNresearch能获得什么?
  13. 宝塔面板是干什么的?有哪些典型的功能作用?
  14. 百度自动驾驶平台生态部负责人张亮:Apollo开放平台,连接技术场景 赋能人才生态
  15. 超详细的八种RAID磁盘阵列原理及优缺点
  16. ADB Interface 找不到驱动程序
  17. 苹果拼图软件测试,视频照片拼图APP
  18. 如何白piao一台优质的华为云服务器
  19. 【C语言】for循环常见问题
  20. excel实现自动排序

热门文章

  1. 使用C++实现的一个五子棋系统(基于Socket编程)
  2. poj3692(二分匹配)
  3. PTA数据结构与算法题目集(中文)7-14
  4. 容斥 + 树形dp ---- 2021 icpc 沈阳 L Perfect Matchings
  5. 用计算机问你叫什么名字,计算器女友与男子谈情说爱 一分钟发出各种甜言蜜语...
  6. 矢量对比_「插画原画必学教程」ps入门——03 图层、位图矢量图、调色
  7. pycharm新建django模板!DOCTYPE html划红线
  8. 20172328《程序设计与数据结构》实验二:树
  9. Apache2.2安装图解
  10. 1013 - 把握趋势