.NET Framework 4부터 도입된 System.Collections.Concurrent 네임스페이스는 여러 스레드가 동시에 접근해도 안전한(thread-safe) 컬렉션 클래스들을 제공합니다. 이러한 컬렉션은 한 번에 여러 스레드가 접근할 수 있다고 해서 동시성 컬렉션(Concurrent Collections)이라고 부르며, 복잡한 잠금(lock) 처리 없이도 데이터 무결성을 보장하고 뛰어난 확장성(scalability)을 발휘합니다.
C#의 주요 동시성 컬렉션 종류
| 번호 | 형식 및 설명 |
|---|---|
| 1 | BlockingCollection<T> 모든 형식에 대해 경계(bounding)와 차단(blocking) 기능을 제공하는 컬렉션입니다. |
| 2 | ConcurrentDictionary<TKey,TValue> 키-값 쌍으로 구성된 사전(Dictionary)의 스레드 안전 구현체입니다. |
| 3 | ConcurrentQueue<T> FIFO(선입선출) 방식 큐의 스레드 안전 구현체입니다. |
| 4 | ConcurrentStack<T> LIFO(후입선출) 방식 스택의 스레드 안전 구현체입니다. |
| 5 | ConcurrentBag<T> 순서가 없는 요소 집합의 스레드 안전 구현체입니다. |
| 6 | IProducerConsumerCollection<T> BlockingCollection에서 사용되기 위해 해당 형식이 반드시 구현해야 하는 인터페이스입니다. |
이번 글에서는 LIFO(후입선출) 방식의 스레드 안전 컬렉션인 ConcurrentStack<T>의 사용법을 살펴보겠습니다.
ConcurrentStack 생성 및 요소 추가
먼저 ConcurrentStack 인스턴스를 생성합니다.
ConcurrentStack<int> s = new ConcurrentStack<int>();
Push 메서드를 호출하여 요소를 추가합니다.
s.Push(1);
s.Push(2);
s.Push(3);
s.Push(4);
s.Push(5);
s.Push(6);
예제 코드
using System;
using System.Collections.Concurrent;
class Demo{
static void Main(){
ConcurrentStack<int> s = new ConcurrentStack<int>();
s.Push(50);
s.Push(100);
s.Push(150);
s.Push(200);
s.Push(250);
s.Push(300);
if (s.IsEmpty){
Console.WriteLine("스택이 비어 있습니다!");
}
else {
Console.WriteLine("스택이 비어 있지 않습니다.");
}
}
}
실행 결과:
스택이 비어 있지 않습니다.
위 예제에서는 Push 메서드로 6개의 정수를 스택에 추가한 뒤, IsEmpty 속성을 통해 스택이 비어 있는지 확인합니다. 요소가 존재하므로 "스택이 비어 있지 않습니다."라는 메시지가 출력됩니다. 이처럼 ConcurrentStack<T>를 활용하면 다중 스레드 환경에서도 안전하게 스택 연산을 수행할 수 있습니다.