面试常考:C#用两个线程交替打印1-100的五种方法

    "C#用两个线程交替打印1-100的五种方法"是.NET工程师面试多线程常考的试题之一,主要考察对C#语法和对多线程的熟悉程度。本文将用5种方法实现这个面试题。

方法1:使用Mutex或lock

    这种方法涉及使用Mutex或lock对象来同步两个线程。其中一个线程负责打印偶数,另一个线程负责打印奇数。线程在执行任务之前会锁定共享的Mutex或lock对象,以确保每个线程执行任务时只有一个线程能够访问共享资源。代码如下:

class Program
{static Mutex mutex = new Mutex();static int count = 1;static void Main(string[] args){Thread t1 = new Thread(PrintOddNumbers);Thread t2 = new Thread(PrintEvenNumbers);t1.Start();t2.Start();t1.Join();t2.Join();Console.ReadLine();}static void PrintOddNumbers(){while (count <= 100){mutex.WaitOne();if (count % 2 == 1){Console.WriteLine("Thread 1: " + count);count++;}mutex.ReleaseMutex();}}static void PrintEvenNumbers(){while (count <= 100){mutex.WaitOne();if (count % 2 == 0){Console.WriteLine("Thread 2: " + count);count++;}mutex.ReleaseMutex();}}
}

方法2:使用AutoResetEvent

AutoResetEvent是一种线程同步机制,允许一个线程等待另一个线程发出信号来继续执行。其中一个线程负责打印奇数,另一个线程负责打印偶数。当一个线程完成打印任务时,它发出信号以唤醒另一个线程来继续执行。

class Program
{static AutoResetEvent oddEvent = new AutoResetEvent(false);static AutoResetEvent evenEvent = new AutoResetEvent(false);static int count = 1;static void Main(string[] args){Thread t1 = new Thread(PrintOddNumbers);Thread t2 = new Thread(PrintEvenNumbers);t1.Start();t2.Start();t1.Join();t2.Join();Console.ReadLine();}static void PrintOddNumbers(){while (count <= 100){if (count % 2 == 1){Console.WriteLine("Thread 1: " + count);count++;evenEvent.Set();oddEvent.WaitOne();}}}static void PrintEvenNumbers(){while (count <= 100){if (count % 2 == 0){Console.WriteLine("Thread 2: " + count);count++;oddEvent.Set();evenEvent.WaitOne();}}}
//欢迎关注公众号“DOTNET开发跳槽”,关注可获得海量面试题

方法3:使用Monitor

Monitor是C#中的一种同步机制,类似于Mutex。其中一个线程负责打印奇数,另一个线程负责打印偶数。线程在执行任务之前会锁定共享的Monitor对象,以确保每个线程执行任务时只有一个线程能够访问共享资源。

class Program
{static object lockObj = new object();static int count = 1;static void Main(string[] args){Thread t1 = new Thread(PrintOddNumbers);Thread t2 = new Thread(PrintEvenNumbers);t1.Start();t2.Start();t1.Join();t2.Join();Console.ReadLine();}static void PrintOddNumbers(){while (count <= 100){lock (lockObj){if (count % 2 == 1){Console.WriteLine("Thread 1: " + count);count++;}}}}static void PrintEvenNumbers(){while (count <= 100){lock (lockObj){if (count % 2 == 0){Console.WriteLine("Thread 2: " + count);count++;}}}}
}

方法4:使用信号量Semaphore

Semaphore是一种同步机制,允许多个线程同时访问共享资源。其中一个线程负责打印奇数,另一个线程负责打印偶数。线程在执行任务之前会等待信号量,以确保每个线程只有在获得信号量之后才能访问共享资源。

  • 
    class Program
    {static Semaphore semaphore = new Semaphore(1, 1);static int count = 1;static void Main(string[] args){Thread t1 = new Thread(PrintOddNumbers);Thread t2 = new Thread(PrintEvenNumbers);t1.Start();t2.Start();t1.Join();t2.Join();Console.ReadLine();}static void PrintOddNumbers(){ //注意 这里是99,否则会出现101while (count <= 99){semaphore.WaitOne();if (count % 2 == 1){Console.WriteLine("Thread 1: " + count);count++;}semaphore.Release();}}static void PrintEvenNumbers(){while (count <= 100){semaphore.WaitOne();if (count % 2 == 0){Console.WriteLine("Thread 2: " + count);count++;}semaphore.Release();}}
    }

方法5:使用Task和async/await

在C#中,使用Task和async/await关键字可以轻松地在两个线程之间切换执行。其中一个线程负责打印奇数,另一个线程负责打印偶数。线程在执行任务之前使用async/await等待异步任务完成,以确保每个线程只在异步任务完成后才访问共享资源。


class Program
{static int count = 1;static void Main(string[] args){Task.Run(PrintOddNumbers);// 这里改成这个也可以// var thread1 = new Thread(PrintOddNumbers);Task.Run(PrintEvenNumbers);Console.ReadLine();}//如果用Thread改成同步方法static async Task PrintOddNumbers(){while (count <= 100){if (count % 2 == 1){Console.WriteLine("Thread 1: " + count);count++;//如果用Thread这里改成 Thread.Sleep(1);await Task.Delay(1);}}}static async Task PrintEvenNumbers(){while (count <= 100){if (count % 2 == 0){Console.WriteLine("Thread 2: " + count);count++;await Task.Delay(1);}}}
//欢迎关注公众号“DOTNET开发跳槽”,关注可获得海量面试题

五种效果如下:

以上五种方法各有优缺点,没有一种方法是绝对最优的,取决于应用场景和要求。以下是对五种方法的简单比较和说明:

1、使用ManualResetEventWaitHandle:这种方法在实现上较为简单,但是由于线程必须互斥地访问共享资源,因此会导致性能瓶颈。此外,使用ManualResetEventWaitHandle需要频繁调用WaitOne和Set方法,可能会降低应用程序的响应能力。

2、使用AutoResetEventWaitHandle:这种方法在实现上比较简单,而且使用AutoResetEventWaitHandle可以避免性能瓶颈问题。然而,它仍然需要频繁调用WaitOne和Set方法,可能会降低应用程序的响应能力。

3、使用锁:使用锁可以避免性能瓶颈问题,因为同一时间只有一个线程可以访问共享资源。但是,锁可能会导致线程死锁和性能下降的问题,因此需要小心使用。

4、使用信号量Semaphore:这种方法可以避免性能瓶颈问题,并允许多个线程同时访问共享资源。Semaphore还可以设置多个许可证,以控制并发线程的数量。然而,使用Semaphore可能会使代码变得更加复杂,因此需要小心使用。

5、使用Task和async/await:这种方法可以避免性能瓶颈问题,并且使用Task和async/await可以使代码更加简洁易懂。但是,它可能会对内存和CPU产生额外的开销,因为需要在任务之间频繁地切换上下文。

综上所述,选择哪种方法取决于应用程序的要求和程序员的个人偏好。如果应用程序需要更好的性能,则应该使用锁或信号量;如果应用程序需要更简洁易懂的代码,则应该使用Task和async/await。

考察的知识点

1、C#编程语言和语法:实现多线程程序需要熟悉C#编程语言和语法,包括线程的创建和管理、共享资源的访问和同步等方面的知识。

2、多线程编程:多线程编程是指同时运行多个线程的编程模型,它可以提高应用程序的性能和响应能力。多线程编程需要考虑线程的同步、共享资源的访问、线程间的通信等问题。

3、线程同步机制:线程同步机制是指用于控制多个线程访问共享资源的机制,常用的线程同步机制包括锁、信号量、事件等。

4、异步编程:异步编程是指不阻塞线程并且在完成任务后通知线程的编程模型,它可以提高应用程序的响应能力和性能。异步编程需要熟悉异步和await关键字、Task和Task<T>等类型、async和await方法等概念。

参考:chatGPT

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/39021.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ChatGPT为什么火?|掀起热潮的对话革命|小智ai

ChatGPT丨小智ai丨chatgpt丨人工智能丨OpenAI丨聊天机器人丨AI语音助手丨GPT-3.5丨开源AI平台|人工智能巨头OpenAI开发的聊天机器人引发全球关注 近期&#xff0c;人工智能领域迎来了一股前所未有的热潮&#xff0c;而其中的主角正是由OpenAI开发的聊天机器人ChatGPT。作为一项…

数据分析案例-股票数据分析

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

图形化跟踪个股RPS走势,挖掘出源源不断的牛股!股票量化分析工具QTYX-V2.5.7...

概述RPS选股策略 威廉欧奈尔把投资理念集中于他自创的CANSLIM选股系统&#xff0c;凭借着这个系统驰骋股票市场数十年&#xff0c;无论在牛市还是熊市&#xff0c;这个系统都是最稳定、表现最好的系统之一。 CANSLIM选股系统中有一个RPS指标&#xff08;Relative Price Strengt…

【树莓派烹饪日记】#1 系统安装与环境配置

0 引言 这个系列用于记录入门树莓派期间踩的各种坑及解决办法。 只记录一些我觉得重要的地方&#xff0c;不一定很全面。 目前暂定的一个目标是拿树莓派接管小爱音箱并接入ChatGPT。 今天的计划是将一个新的树莓派主板 烧录并启动系统系统配置安装VPN安装conda环境 需要用到…

RWKV配上ChatGPTBox让我们在浏览器中感受AI带来的魅力

这次我们来讲讲RWKV搭配ChatGPTBox结合使用带来的功能体验&#xff0c;这两个项目都是同一个大神创建的&#xff0c;完全可以无缝搭配进行使用。 以下是我之前在本地部署了AI模型RWKV的教程&#xff0c;如果还没有本地部署过AI的童鞋可以查看我之前发布的教程&#xff0c;在自…

总结谷歌身份验证器 Google Authenticator 的详细使用方法

谷歌身份验证器Google Authenticator是谷歌推出的一款动态口令工具&#xff0c;解决大家各平台账户遭到恶意攻击的问题&#xff0c;一般在相关的服务平台登陆中除了用正常用户名和密码外&#xff0c;需要再输入一次谷歌认证器生成的动态口令才能验证成功&#xff0c;相当于输入…

快速接入Google两步认证Google Authenticator

(一)介绍 既然来看该文章就应该知道Google的两步认证是干什么的&#xff0c;这边再提供一次app的下载链接 (apkpure搜索谷歌身份验证器) 验证原理讲解&#xff1a; 在数据库中查找该登陆用户之前绑定的32位随机码&#xff08;该码一般会存入数据库&#xff09;调用API传入32位…

身份验证器 Authenticator 插件

1.插件支持浏览器 ChromeFirefoxEdge 2.关键特性 通过扫描二维码添加账号使用密码加密数据在浏览器之间同步数据备份数据到云服务或导出数据到文件智能过滤和搜索 官网地址: Authenticator Extension 官方说明文档&#xff1a;What is Authenticator Extension? | Authen…

前后端身份验证

1、web 开发模式 【】基于服务端渲染的传统 Web 开发模式 【】基于前后端分离的新型 Web 开发模式&#xff1a;依赖于 Ajax 技术的广泛应用。后端只负责提供 API 接口&#xff0c;前端使用 Ajax 调用接口的开发模式 2、身份认证 【】服务端渲染推荐使用 Session 认证机制 【】…

生信工作流框架搭建 | 04-nextflow与Slurm高性能计算

目录 生信工作流框架搭建 | 04-nextflow与Slurm高性能计算前情提要什么是HPC高性能计算什么是slurm nextflow配置注意事项下期预告 生信工作流框架搭建 | 04-nextflow与Slurm高性能计算 本篇为biodoge《生信工作流框架搭建》系列笔记的第5篇&#xff0c;该系列将持续更新。 前情…

评价基于GPT和Bert的方法并用于生信文本识别PPI

检测蛋白质-蛋白质相互作用&#xff08;PPI&#xff09;对于理解遗传机制、疾病发病机制和药物设计至关重要。然而&#xff0c;随着生物医学文献的快速增长&#xff0c;越来越需要自动和准确地提取PPI以促进科学知识发现。预训练语言模型&#xff0c;例如生成式预训练Transform…

Limma | 三个组的差异分析怎么分析做呢!?~

1写在前面 高考结束了&#xff0c;不知道各位考生考的怎么样&#xff0c;这种时候总是几家欢喜几家忧&#xff0c;但这也是实现阶级流动的最佳机会。&#x1f914; 回想自己高考过去10几年了&#xff0c;不能说学了医后悔吧&#xff0c;只能说后悔至极&#xff0c;苦不堪言啊&a…

生信分析案例 Python简明教程 | 视频13

开源生信 Python教程 生信专用简明 Python 文字和视频教程 源码在&#xff1a;https://github.com/Tong-Chen/Bioinfo_course_python 目录 背景介绍 编程开篇为什么学习Python如何安装Python如何运行Python命令和脚本使用什么编辑器写Python脚本Python程序事例Python基本语法 数…

生信分析案例 Python简明教程 | 视频12

开源生信 Python教程 生信专用简明 Python 文字和视频教程 源码在&#xff1a;https://github.com/Tong-Chen/Bioinfo_course_python 目录 背景介绍 编程开篇为什么学习Python如何安装Python如何运行Python命令和脚本使用什么编辑器写Python脚本Python程序事例Python基本语法 数…

生信分析案例 Python简明教程 | 视频11

开源生信 Python教程 生信专用简明 Python 文字和视频教程 源码在&#xff1a;https://github.com/Tong-Chen/Bioinfo_course_python 目录 背景介绍 编程开篇为什么学习Python如何安装Python如何运行Python命令和脚本使用什么编辑器写Python脚本Python程序事例Python基本语法 数…

12款好用的Visual Studio插件,最后一款良心推荐

工欲善其事&#xff0c;必先利其器,整理的一些我必装的12款Visual Studio插件&#xff0c;希望你们能get到。 效率工具前文传送门&#xff1a; adb常用命令总结 程序员你可以考虑安装的15款谷歌插件 推荐20套实战源码 99%的人不知道搜索引擎的6个技巧 12款好用的Visual Stu…

七年磨一剑!苹果王炸产品Vision Pro诞生,未来已来

这是第一款「不见却可透见」的苹果产品 等了整整七年&#xff01;2023年6月5日&#xff0c;WWDC23大会上&#xff0c;苹果发布首款头显Vision Pro&#xff0c;Vision Pro 可以算是苹果公司自 2015 年 Apple Watch 首次亮相以来最大的硬件产品发布&#xff0c;或许它会彻底改变数…

chatgpt赋能python:人机对话Python——让交互更智能

人机对话Python——让交互更智能 随着科技的不断发展&#xff0c;人类与机器之间的交互方式也在不断改变。从最初的键盘输入和鼠标点击&#xff0c;到现在的语音识别和手势交互&#xff0c;我们与计算机之间的交互方式日益智能化和自然化。人机对话技术就是其中一种重要的交互…

紫砂典故之“蔓生石瓢”

紫砂典故之“蔓生石瓢”

如何区分纯正紫砂底料

首先大家要区分一个概念&#xff0c;就是纯正的底料和调砂不是同一个概念&#xff0c;调砂其实是紫泥中的石英颗粒&#xff0c;调砂可以增强泥料的可塑性&#xff0c;增强了透气性&#xff0c;以及增加质感。纯的底料&#xff0c;不是那么坚硬&#xff0c;经过一到两天&#xf…