본문 바로가기
프로그래밍/C#

Queue vs ConcurrentQueue로 쓰레드 환경에서 테스트

by bantomak 2023. 6. 27.

Queue로 실행한 경우

thread-safe가 보장되지 않은 Queue로 큐를 선언

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

class CQ_EnqueueDequeuePeek
{
    static void Main()
    {
        Queue<int> cq = new Queue<int>();

        for (int i = 0; i < 100; i++)
        {
            cq.Enqueue(i);
        }

        int outerSum = 0;

        Action action = () =>
        {
            int localSum = 0;
            int localValue;

            while (cq.TryDequeue(out localValue))
            {
                localSum += localValue;
            }
            
            outerSum += localSum;
        };

        Parallel.Invoke(action, action, action, action);

        Console.WriteLine($"outerSum = {outerSum}");
    }
}

 

알수 없는 값이 출력

 

ConcurrentQueue로 실행한 경우

thread-safe한 선입선출 방식의 ConcurrentQueue로 큐를 선언

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

class CQ_EnqueueDequeuePeek
{
    static void Main()
    {
        ConcurrentQueue<int> cq = new ConcurrentQueue<int>();

        for (int i = 0; i < 100; i++)
        {
            cq.Enqueue(i);
        }

        int outerSum = 0;

        Action action = () =>
        {
            int localSum = 0;
            int localValue;

            while (cq.TryDequeue(out localValue))
            {
                localSum += localValue;
            }
            
            outerSum += localSum;
        };

        Parallel.Invoke(action, action, action, action);

        Console.WriteLine($"outerSum = {outerSum}");
    }
}

다중으로 실행했지만 마치 하나의 함수만 실행한거같은 결과가 나타납니다.

 

0부터 99까지의 합이 정상적으로 출력

 

참조 사이트

 

ConcurrentQueue<T> 클래스 (System.Collections.Concurrent)

스레드로부터 안전한 FIFO(선입선출) 방식의 컬렉션을 나타냅니다.

learn.microsoft.com

댓글