首页 > 编程语言 >c#中使用lock创建一个简单的队列示例

c#中使用lock创建一个简单的队列示例

时间:2024-09-18 10:47:53浏览次数:9  
标签:示例 c# lock queue 队列 线程 item new

一.背景

在我威某人的浅薄理解下,队列主要解决的问题,确保某些场景可以按顺寻处理避免混乱和延误并且可以按优先级入队处理,比较常见的场景有以下这五点:

1.订单处理和物流管理

2.客户服务和支持

3.数据处理和分析

4.任务调度和执行

5.消息传递和通信

二.实现:

1.首先我们创建一个简单的队列帮助类如下图

 

2.帮助类中的代码

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace ConsoleApp1.Models
 8 {
 9     public class SimpleQueue<T>
10     {
11         private readonly Queue<T> _queue = new Queue<T>();
12         private readonly object _lock = new object();  // 锁对象
13 
14         // 入队操作
15         public void Enqueue(T item)
16         {
17             lock (_lock)  // 确保线程安全
18             {
19                 _queue.Enqueue(item);
20                 Console.WriteLine($"Item enqueued: {item}");
21             }
22         }
23 
24         // 出队操作
25         public T Dequeue()
26         {
27             lock (_lock)  // 确保线程安全
28             {
29                 if (_queue.Count == 0)
30                 {
31                     throw new InvalidOperationException("Queue is empty");
32                 }
33 
34                 T item = _queue.Dequeue();
35                 Console.WriteLine($"Item dequeued: {item}");
36                 return item;
37             }
38         }
39 
40         // 查看队列是否为空
41         public bool IsEmpty()
42         {
43             lock (_lock)
44             {
45                 return _queue.Count == 0;
46             }
47         }
48     }
49 }

如何调用:

如下是在Program中调用代码,代码细节请查看注释

 1 // See https://aka.ms/new-console-template for more information
 2 using ConsoleApp1.Models;
 3 
 4 Console.WriteLine("Hello, World!");
 5 var queue = new SimpleQueue<int>();
 6 
 7 // 创建生产者线程
 8 Thread producer = new Thread(() =>
 9 {
10     for (int i = 0; i < 10; i++)
11     {
12         queue.Enqueue(i);
13         Thread.Sleep(100);  // 模拟一些延迟
14     }
15 });
16 
17 // 创建消费者线程
18 Thread consumer = new Thread(() =>
19 {
20     for (int i = 0; i < 10; i++)
21     {
22         if (!queue.IsEmpty())
23         {
24             queue.Dequeue();
25         }
26         Thread.Sleep(150);  // 模拟一些延迟
27     }
28 });
29 
30 producer.Start();
31 consumer.Start();
32 
33 producer.Join();
34 consumer.Join();
35 
36 Console.WriteLine("Queue processing completed.");

运行结果如下图:

代码说明:

  • 队列的基本操作

    • Enqueue(T item):将元素添加到队列尾部。
    • Dequeue():从队列头部移除并返回一个元素。
    • IsEmpty():检查队列是否为空。
  • 线程安全

    • 使用了 lock 关键字,它将某一代码块包裹起来,使同一时间只能有一个线程进入该代码块,其他线程会被阻塞,直到当前线程释放锁。
    • 锁定的是 _lock 对象,这个对象在整个队列生命周期中保持唯一,确保对队列的每次操作(入队、出队等)是互斥的

 总结:

好的终于到了大家伙最不舍的总结环节,那让我来总结一下吧!!!

  • 优点

    • 简单明了,使用 lock 可以确保对共享资源的访问是安全的,不会产生并发问题。
    • 适合简单的队列需求,代码易于理解和维护。
  • 缺点

    • 锁的使用会导致线程阻塞,尤其在高并发环境下,大量的线程可能因为竞争锁而等待,降低了性能。
    • 锁的使用并不高效,特别是在大量入队、出队操作时,可能会带来不必要的开销。

 虽然使用锁可以实现线程安全的队列,但在高并发场景下,锁的开销可能比较高。如果需要高并发性能可以考虑使用无锁队列如 .NET 中的 ConcurrentQueue<T>)或其他更复杂的并发控制机制来优化性能。

标签:示例,c#,lock,queue,队列,线程,item,new
From: https://www.cnblogs.com/shenweif/p/18418063

相关文章

  • Leetcode 315. 计算右侧小于当前元素的个数
    1.题目基本信息1.1.题目描述给你一个整数数组nums,按要求返回一个新数组counts。数组counts有该性质:counts[i]的值是nums[i]右侧小于nums[i]的元素的数量。1.2.题目地址https://leetcode.cn/problems/count-of-smaller-numbers-after-self/description2.解题方法......
  • commonJs和ESModule的区别
    1.规范的区别ESM模块的导入使用Import关键字,导出使用export关键字。commonJs导入使用require关键字,导出使用module.export 2.文件名后缀不一样(这一点不用记,针对Node)在node.js,默认将.js后缀文件识别为CJS模块,.cjs也是CJS模块,.mjs文件识别为esm模块。 3.模块加载时机......
  • [昌哥IT课堂]|欢迎 MySQL 9.0,回顾 Oracle 在 8.0 版中的管理(译)
    对于新兴技术和社区的管理是相对容易的。经过29年发展,MySQL已成为全球数百万用户中使用最广泛且备受信任的开源数据库之一。在这一规模的社区领导中可能存在复杂性。我们努力寻求稳定和创新的平衡,为客户提供稳定可预测的平台,并为技术用户提供新功能。Oracle通过投资于技术的工......
  • 使用 Wake Lock API:保持设备唤醒的最佳实践
    在现代Web应用中,尤其是涉及视频播放、实时通信、地图导航等长时间运行的任务时,用户常常希望设备不要因为空闲而自动进入睡眠模式或屏幕变暗。为了解决这一问题,WebAPI提供了一个名为WakeLock的接口,允许开发者请求设备保持唤醒状态。本文将详细介绍如何使用WakeLockAPI......
  • musl libc 与 glibc 在 .NET 应用程序中的兼容性
    muslLinux和glibc是两种不同的C标准库实现,它们在多个方面存在显著差异。历史和使用情况:glibc是较早且广泛使用的C标准库实现,具有较长的开发历史和广泛的社区支持。它被大多数Linux发行版采用,特别是在桌面和服务器环境中。musl是一个相对较新的实现,旨在提供更小、更快......
  • Gbase 8a支持DATE_TO_CHAR 函数
    DATE_TO_CHAR函数,功能是把日期格式化为YYYY-MIM-DD格式(format格式)的字符串;使用格式为:DATETO_CHAR(date,format)说明:date,日期类型;format,格式字符串;在开启控制参数时,format为可选参数,不输入format,默认为YYYY-MM-DD。DATE_TO_CHAR函数的使用优点众多,具体如下:1、提高......
  • 数据控制语言(DCL,Data Control Language)
    目录GRANT语句REVOKE语句权限类型数据控制语言(DCL,DataControlLanguage)用于管理数据库中的权限和访问控制。DCL语句主要用于控制用户对数据库对象的访问权限。常见的DCL语句有GRANT和REVOKE。GRANT语句GRANT语句用于授予用户或角色对数据库对象(如表、视图......
  • CSP-J/S复赛提交指南!防止爆零必读!
    文件提交模版代码:#include<bits/stdc++.h>usingnamespacestd;intmain(){//打开输入文件,输出文件freopen("test.in","r",stdin);freopen("test.out","w",stdout);//正常的逻辑代码//关闭输入文件输出文件fclose(stdin);......
  • .NET 9 RC1 正式发布,ASP.NET Core 得到完善
    .NET9RC1是.NET9的第一个候选发布版本(ReleaseCandidate),标志着该版本接近最终发布。这次更新包括增强的WebSocketAPI、新的压缩选项、高级SignalR跟踪以及.NETMAUI的更新,以改善文本对齐等。在文章还宣布了.NETConf2024的日期,将于2024年11月12日至14日举行,庆祝.NET9的发......
  • GBase GCDW warehouse相关权限
    GCDW中,warehouse相关权限有三个,MODIFY_WAREHOUSE、OPERATE_WAREHOUSE、USAGE_WAREHOUSE;对应功能如下:MODIFY_WARHEOUSE:允许角色创建,删除,启动,挂起,修改warehouse属性的权限。OPERATE_WAREHOUSE:允许角色使用warehouse资源执行sql的权限,同时如果目标warehouse正处于suspend......