C#에서 ArrayList에 대한 동기화된 래퍼를 만들려면 정적 메서드인 ArrayList.Synchronized()를 사용합니다. 이 메서드는 기존 ArrayList를 감싸는 스레드로부터 안전한(thread-safe) 래퍼 객체를 반환합니다.
ArrayList가 동기화되어 있는지 여부는 IsSynchronized 속성으로 확인할 수 있습니다. 일반적인 ArrayList는 기본적으로 동기화되어 있지 않기 때문에 이 속성은 False를 반환합니다.
예제 1: 기본 ArrayList의 동기화 상태 확인
먼저 일반 ArrayList를 생성하고 요소를 추가한 뒤, 동기화 여부를 확인해 보겠습니다.
using System;
using System.Collections;
public class Demo {
public static void Main() {
ArrayList arrList = new ArrayList();
arrList.Add("AB");
arrList.Add("CD");
arrList.Add("EF");
arrList.Add("GH");
arrList.Add("IJ");
arrList.Add("KL");
Console.WriteLine("ArrayList elements...");
foreach(string str in arrList) {
Console.WriteLine(str);
}
Console.WriteLine("ArrayList is synchronized? = "+arrList.IsSynchronized);
}
}출력 결과
위 코드를 실행하면 다음과 같은 결과가 출력됩니다.
ArrayList elements... AB CD EF GH IJ KL ArrayList is synchronized? = False
출력에서 확인할 수 있듯이, 일반 ArrayList의 IsSynchronized 값은 False입니다. 즉, 여러 스레드가 동시에 접근하면 데이터 불일치나 예외가 발생할 수 있습니다.
예제 2: Synchronized() 메서드로 동기화된 래퍼 만들기
이번에는 ArrayList.Synchronized() 메서드를 사용하여 동기화된 래퍼를 생성하고, 그 결과를 비교해 보겠습니다.
using System;
using System.Collections;
public class Demo {
public static void Main() {
ArrayList arrList = new ArrayList();
arrList.Add("AB");
arrList.Add("CD");
arrList.Add("EF");
arrList.Add("GH");
arrList.Add("IJ");
arrList.Add("KL");
Console.WriteLine("ArrayList elements...");
foreach(string str in arrList) {
Console.WriteLine(str);
}
Console.WriteLine("ArrayList is synchronized? = "+arrList.IsSynchronized);
ArrayList arrList2 = ArrayList.Synchronized(arrList);
Console.WriteLine("ArrayList is synchronized? = "+arrList2.IsSynchronized);
}
}출력 결과
위 코드를 실행하면 다음과 같은 결과가 출력됩니다.
ArrayList elements... AB CD EF GH IJ KL ArrayList is synchronized? = False ArrayList is synchronized? = True
핵심 정리
ArrayList.Synchronized(list)는 전달받은 리스트를 감싸는 동기화된 래퍼를 반환합니다.- 래퍼의
IsSynchronized속성은 True이며, 내부적으로 읽기·쓰기 작업 시 자동으로 잠금(lock)을 처리합니다. - 단, 열거(enumeration) 중에는 여전히 수동으로 컬렉션을 잠가야 하므로, 멀티스레드 환경에서는
lock문과 함께 사용하는 것이 안전합니다. - 새로운 프로젝트에서는 제네릭 컬렉션인
List<T>사용이 권장되며, 스레드 안전성이 필요하다면ConcurrentBag<T>,ConcurrentQueue<T>같은 동시성 컬렉션을 고려하는 것이 좋습니다.