当前位置: 首页 > article >正文

C# 队列的各种使用方法 private static ConcurrentQueue

        在C#中,ConcurrentQueue<T> 是一个线程安全的先进先出(FIFO)集合,它位于 System.Collections.Concurrent 命名空间中。它非常适合在多线程环境中使用,因为它提供了一些原子操作来确保线程安全。

以下是一些常见的 ConcurrentQueue<T> 使用方法,以 ConcurrentQueue<string> 为例:

1. 初始化队列

using System;
using System.Collections.Concurrent;

class Program
{
    private static ConcurrentQueue<string> queue = new ConcurrentQueue<string>();

    static void Main(string[] args)
    {
        // 其他代码
    }
}

2. 入队(Enqueue)

使用 Enqueue 方法将元素添加到队列的末尾。

queue.Enqueue("First item");
queue.Enqueue("Second item");

3. 出队(Dequeue)

使用 TryDequeue 方法从队列的开头移除并返回元素。这是一个返回布尔值的操作,因为队列可能为空。

if (queue.TryDequeue(out string result))
{
    Console.WriteLine($"Dequeued: {result}");
}
else
{
    Console.WriteLine("Queue is empty.");
}

4. 查看队首元素(Peek)

使用 TryPeek 方法查看队列的开头元素但不移除它。

if (queue.TryPeek(out string peekResult))
{
    Console.WriteLine($"Peek: {peekResult}");
}
else
{
    Console.WriteLine("Queue is empty.");
}

5. 检查队列是否为空

虽然 TryDequeue 和 TryPeek 可以通过返回值检查队列是否为空,但你也可以直接检查 IsEmpty 属性。

if (queue.IsEmpty)
{
    Console.WriteLine("Queue is empty.");
}
else
{
    Console.WriteLine("Queue is not empty.");
}

6. 遍历队列

虽然 ConcurrentQueue<T> 不支持直接遍历(因为遍历期间可能会有其他线程修改队列),但你可以通过循环和 TryDequeue 方法安全地遍历所有元素,同时清空队列。

while (!queue.IsEmpty)
{
    if (queue.TryDequeue(out string item))
    {
        Console.WriteLine(item);
    }
}

或者,如果你不想清空队列,可以使用一个临时队列来复制元素,然后遍历临时队列:

ConcurrentQueue<string> tempQueue = new ConcurrentQueue<string>(queue);

foreach (var item in tempQueue)
{
    Console.WriteLine(item);
}

7. 线程安全操作

ConcurrentQueue<T> 的所有公共和受保护成员都是线程安全的,并且可以在多个线程上并发使用,而无需额外的锁定。

示例代码

以下是一个完整的示例,展示了上述方法的使用:

using System;
using System.Collections.Concurrent;
using System.Threading.Tasks;

class Program
{
    private static ConcurrentQueue<string> queue = new ConcurrentQueue<string>();

    static void Main(string[] args)
    {
        // 入队
        queue.Enqueue("Item 1");
        queue.Enqueue("Item 2");
        queue.Enqueue("Item 3");

        // 查看队首元素
        if (queue.TryPeek(out string peekResult))
        {
            Console.WriteLine($"Peek: {peekResult}");
        }

        // 并发处理
        Parallel.For(0, 5, i =>
        {
            ProcessQueue();
        });

        // 清空并遍历队列
        while (!queue.IsEmpty)
        {
            if (queue.TryDequeue(out string item))
            {
                Console.WriteLine($"Dequeued: {item}");
            }
        }
    }

    static void ProcessQueue()
    {
        while (!queue.IsEmpty)
        {
            if (queue.TryDequeue(out string item))
            {
                Console.WriteLine($"Thread {Task.CurrentId} processed: {item}");
            }
        }
    }
}

请注意,由于多个线程同时尝试处理队列,因此某些元素可能会被多个线程检查到但只有一个线程能成功出队。这就是 ConcurrentQueue<T> 线程安全性的体现。


http://www.kler.cn/a/487782.html

相关文章:

  • 【LeetCode】力扣刷题热题100道(21-25题)附源码 接雨水 合并区间 字母异位词 滑动窗口 覆盖子串(C++)
  • 精度论文:【Coordinate Attention for Efficient Mobile Network Design】
  • 高等数学学习笔记 ☞ 一元函数微分的基础知识
  • Spring Boot教程之四十九:Spring Boot – MongoRepository 示例
  • VSCode Live Server 插件安装和使用
  • Matplotlib 直方图:数据可视化基础
  • 《跨西伯利亚铁路模拟器抢先版》Build16645718官方中文学习版
  • GPTs与鸿蒙HarmonyOS应用开发的深度融合:探索与实践
  • 1. 使用springboot做一个音乐播放器软件项目【前期规划】
  • 28.Java 实现线程间定制化通信
  • 学英语学压测:08 jmeter html测试报告测试报告的3种生成方式
  • linux截取日志信息
  • Nginx:HTTP 方法控制
  • 解决idea中无法拖动tab标签页的问题
  • [Unity]发包前遇到的坑之GridLayoutGroup
  • Nginx不支持HTTP请求头中包含下划线_的解决办法
  • 详解 Docker 启动 Windows 容器第一篇:多种方式及实用配置指南
  • [IoT]详细设计:智能农业监控系统
  • LabVIEW轴承性能测试系统
  • 【HTML+CSS+JS+VUE】web前端教程-27-弹性盒模型(flex box)
  • uniapp小程序中隐藏顶部导航栏和指定某页面去掉顶部导航栏小程序
  • 江科大STM32入门——输入捕获笔记总结
  • Makefile文件/其他文件中出现的“变量/符合”,如何查看定义?
  • verilogHDL仿真详解
  • JavaFx 21 项目Markdown 预览、编辑、新建、文件树、删除、重命名
  • huggingface上下载数据