C#

C# Queue 자료구조 (feat Thread-safe한 ConcurrentQueue)

sheepone 2021. 6. 30. 11:09
반응형

선입선출(FIFO, First In First Out) 구조

맨뒤에 데이터를 추가하고 맨 앞에서 데이터가 출력

 

큐가 비어 있을때 에러 System.InvalidOperationException: '큐가 비어 있습니다.'

 

일반 Queue

using System;
using System.Collections.Generic;

namespace ConsoleApp11
{
    class Program
    {
        static void Main(string[] args)
        {
            Queue<int> numbers = new Queue<int>();
            numbers.Enqueue(1); //큐에 데이터 추가
            numbers.Enqueue(2);
            numbers.Enqueue(3);

            int iDequeue = 0 ;

            iDequeue = numbers.Peek(); //큐의 데이터를 제거하기 않고 가져오기
            Console.WriteLine(iDequeue); 

            iDequeue = numbers.Dequeue(); //큐의 데이터 반환
            Console.WriteLine(iDequeue); //output 1

            iDequeue = numbers.Dequeue(); //큐의 데이터 반환
            Console.WriteLine(iDequeue); //output 2

            iDequeue = numbers.Dequeue(); //큐의 데이터 반환
            Console.WriteLine(iDequeue); //output 3

            if(numbers.Count > 0) //큐에 남은 데이터 확인
            {
                iDequeue = numbers.Dequeue(); //큐의 데이터 반환
                Console.WriteLine(iDequeue); //output 
            }

            Console.ReadLine();
        }
    }
}

 

Thread-safe한 ConcurrentQueue

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

namespace ConsoleApp11
{
    class Program
    {
        static void Main(string[] args)
        {
            // Thread-safe한 Wrapper 큐
            ConcurrentQueue<int> numbers = new ConcurrentQueue<int>();

            // 데이타를 큐에 넣는 쓰레드
            Task tEnqueue = Task.Factory.StartNew(() =>
            {
                for (int i = 0; i < 100; i++)
                {
                    numbers.Enqueue(i);
                    Thread.Sleep(10);
                }
            });

            // 데이타를 큐에서 읽는 쓰레드
            Task tDequeue = Task.Factory.StartNew(() =>
            {
                int count = 0;
                while (count < 100)
                {
                    if (numbers.TryDequeue(out int result))
                    {
                        Console.WriteLine(result); // output : 0~99
                        count++;
                    }
                    Thread.Sleep(10);
                }
            });

            // 두 쓰레드가 끝날 때까지 대기
            Task.WaitAll(tEnqueue, tDequeue);

            Console.ReadLine();
        }
    }
}

 

반응형