.Net은 개발자가 경합을 줄이고 애플리케이션 성능을 향상시킬 수 있는 모든 원자 작업에 대해 "Interlocked" 클래스라는 강력한 도구를 제공합니다.
다중 스레드 애플리케이션 시나리오에서 기존 잠금 기술을 사용하면 원자성 작업에 대한 성능 병목 현상이 발생할 수 있습니다. .Net은 개발자가 경합을 줄이고 애플리케이션 성능을 향상시킬 수 있는 모든 원자 작업에 대해 "Interlocked" 클래스라는 강력한 도구를 제공합니다.
전통적으로 여러 스레드가 공유 리소스에 액세스할 때 스레드 안전을 보장하기 위해 개발자는 잠금을 사용합니다. 잠금을 사용하면 여러 스레드가 동시에 중요한 코드 섹션에 진입하는 것을 방지할 수 있으므로 한 번에 하나의 스레드만 공유 리소스를 수정할 수 있습니다.
private int _counter; private readonly object _syncRoot = new object(); public void IncrementCounter() { lock (_syncRoot) { _counter++; } }
앞서 언급한 접근 방식은 여러 스레드가 동시에 잠금에 액세스하려고 시도할 때 잠금을 성공적으로 획득한 스레드를 제외하고 보류 상태가 되는 경합이라는 잠재적인 성능 문제의 위험을 초래합니다.
.NET 프레임워크는 원자성 작업을 효율적으로 수행하도록 설계된 System.Threading 네임스페이스의 일부로 Interlocked 클래스를 제공합니다. 원자적 작업은 분할할 수 없습니다. 중단 없이 완전히 완료됩니다.
private int _counter; public void IncrementCounter() { Interlocked.Increment(ref _counter); }
Interlocked 클래스는 잠금이 필요하지 않으므로 기존 접근 방식에서 언급한 경합 문제를 해결합니다.
새 클래스 이름 IncrementClass를 추가하고 다음 코드 조각을 추가합니다.
public static class IncrementClass { private static int _counter = 0; /// <summary> /// Outputs /// Counter value: 10 /// </summary> public static void TestIncrementCounter() { // Create an array to hold the tasks Task[] tasks = new Task[10]; // Initialize and start tasks for (int i = 0; i < tasks.Length; i++) { tasks[i] = Task.Run(() => IncrementCounter()); } // Wait for all tasks to complete Task.WaitAll(tasks); Console.WriteLine($"Counter value: {_counter}"); } public static void IncrementCounter() { // Safely increment the counter across multiple threads Interlocked.Increment(ref _counter); } }
다음과 같이 기본 메서드에서 호출합니다.
#region Day 17: Increment Class IncrementClass.TestIncrementCounter(); #endregion
콘솔 출력:
Counter value: 10
GitHub — ssukhpinder/30DayChallenge.Net
C# 커뮤니티의 일원이 되어주셔서 감사합니다! 가기 전에: