C#队列(Queue)及泛型类(Queue<T>)

队列实现先进先出,有装箱拆箱行为,可存放任意类型,但无法获取指定位置元素,只能取出最先存储的元素。
一、基本队列操作
1、向队列添加元素(Enqueue)

Queue queue = new Queue();
queue.Enqueue(1);
queue.Enqueue("道,可道,非常道。");
queue.Enqueue(1.21);
queue.Enqueue("白马非马。");
 queue.Enqueue(-5.68);
queue.Enqueue("事虽难,做则必成。");

2、获取队列长度(Count)

Console.WriteLine("队列长度:" + queue.Count);

3、队列遍历

if (queue != null && queue.Count > 0)
 {
     foreach (var item in queue)
     {
        Console.WriteLine(item);
     }
}

4、读取取出(Peek)

Console.WriteLine("队列读取取出");
var value = queue.Peek();
Console.WriteLine(value);

5、删除取出(Dequeue)

Console.WriteLine("队列删除取出");
var value1 = queue.Dequeue();
Console.WriteLine(value1);

6、判断元素是否存在(Contains)

Console.WriteLine("判断队列中元素是否存在");
if (queue.Contains(1.21))
 {
     Console.WriteLine("队列中存在1.21");
 }

7、清空队列(Clear)

Console.WriteLine("清空队列");
queue.Clear();

二、泛型类队列
1、示例

Queue<string> queue = new Queue<string>();
        queue.Enqueue("远上寒山石径斜");
        queue.Enqueue("白云深处有人家");
        queue.Enqueue("停车坐爱枫林晚");
        queue.Enqueue("霜叶红于二月花");

        int count = queue.Count;
        Console.WriteLine("队列元素数量:"+count);

        bool b = queue.Contains("老六");
        string res = b ? "队列中包括老六" : "队列中不包括老六";
        Console.WriteLine(res);

        Console.WriteLine("Peek测试");
        string p = queue.Peek();
        Console.WriteLine(p);

        Console.WriteLine("Dequeue测试");
        string d1 = queue.Dequeue();
        Console.WriteLine(d1);
        d1 = queue.Dequeue();
        Console.WriteLine(d1);

        Console.WriteLine("Clear测试");
        queue.Clear();
        Console.WriteLine(queue.Count);

2、运行结果
队列元素数量:4
队列中不包括老六
Peek测试
远上寒山石径斜
Dequeue测试
远上寒山石径斜
白云深处有人家
Clear测试
0
三、队列多线程操作
1、示例

static Queue<int> queueT = new Queue<int>();
        static readonly object objLock = new object();
        public const int THREAD_SUM = 5;

        public static void QueueTest()
        {
            queueT.Clear();
            for(int i = 0; i < 30; i++)
            {
                queueT.Enqueue(i);
            }
            var factory=new TaskFactory();
            var tasks=new Task[THREAD_SUM];
            for(int i=0;i < THREAD_SUM; i++)
            {
                Task task = tasks[i];
                task = factory.StartNew(() =>
                {
                    Timer timer = new Timer((o) =>
                    {
                        if (IsAvailable)
                        {
                            int q = Read();
                            Console.WriteLine($"线程{task.Id}读取值:{q}");
                        }
                    }, null, 500, 1000);
                });
            }
        }

        public static int Read()
        {
            int res = 0;
            lock(objLock)
            {
                if(IsAvailable)
                {
                    res=queueT.Dequeue();
                }
                return res;
            }
        }

        public static bool IsAvailable
        {
            get { return queueT.Count > 0; }
        }

2、运行结果

线程1读取值:0
线程3读取值:1
线程5读取值:2
线程4读取值:3
线程2读取值:4
线程3读取值:5
线程1读取值:6
线程4读取值:7
线程5读取值:8
线程2读取值:9
线程3读取值:10
线程1读取值:11
线程5读取值:12
线程4读取值:13
线程2读取值:14
线程3读取值:15
线程1读取值:16
线程5读取值:17
线程2读取值:19
线程4读取值:18
线程3读取值:23
线程5读取值:21
线程2读取值:22
线程1读取值:24
线程4读取值:20
线程5读取值:25
线程3读取值:28
线程1读取值:29
线程4读取值:26
线程2读取值:27

注意:线程号和数据的对应关系并不确定,但所有队列元素全部遍历到。