본문 바로가기
개발/기본) 기본기

기본기)c#) lock

by 테샤르 2021. 5. 12.

lock 문

lock은 특정 상황에서 상호 배제 잠금을 하는 키워드로 해당 상황에서는 lock을 걸게되면 다른곳에서 자원을 사용하지 못하도록 독립적인 상황을 만드는 방법이다.

대부분은 병렬적으로 처리가되는 형태에서 데이터의 무결성을 확보하기 위해서 사용을 하게되는데 형식은 다음과 같다.

lock(x)
{

//Your code..
}

예제는 다음과 같다.

 

 전용 balanceLock 인스턴스에 잠금을 설정하여 해당 개인 balance 필드에 대한 액세스를 동기화하는 Account 클래스를 정의합니다. 동일한 인스턴스를 잠금에 사용하면 Debit 또는 Credit 메서드를 동시에 호출하려는 두 스레드에 의해 balance 필드가 동시에 업데이트되지 않습니다.

using System;
using System.Threading.Tasks;

public class Account
{
    private readonly object balanceLock = new object();
    private decimal balance;

    public Account(decimal initialBalance) => balance = initialBalance;

    public decimal Debit(decimal amount)
    {
        if (amount < 0)
        {
            throw new ArgumentOutOfRangeException(nameof(amount), "The debit amount cannot be negative.");
        }

        decimal appliedAmount = 0;
        lock (balanceLock)
        {
            if (balance >= amount)
            {
                balance -= amount;
                appliedAmount = amount;
            }
        }
        return appliedAmount;
    }

    public void Credit(decimal amount)
    {
        if (amount < 0)
        {
            throw new ArgumentOutOfRangeException(nameof(amount), "The credit amount cannot be negative.");
        }

        lock (balanceLock)
        {
            balance += amount;
        }
    }

    public decimal GetBalance()
    {
        lock (balanceLock)
        {
            return balance;
        }
    }
}

class AccountTest
{
    static async Task Main()
    {
        var account = new Account(1000);
        var tasks = new Task[100];
        for (int i = 0; i < tasks.Length; i++)
        {
            tasks[i] = Task.Run(() => Update(account));
        }
        await Task.WhenAll(tasks);
        Console.WriteLine($"Account's balance is {account.GetBalance()}");
        // Output:
        // Account's balance is 2000
    }

    static void Update(Account account)
    {
        decimal[] amounts = { 0, 2, -3, 6, -2, -1, 8, -5, 11, -6 };
        foreach (var amount in amounts)
        {
            if (amount >= 0)
            {
                account.Credit(amount);
            }
            else
            {
                account.Debit(Math.Abs(amount));
            }
        }
    }
}

 

Microsoft Doc : [ 링크 ]

 

lock 문 - C# 참조

C# lock 문을 사용하여 공유 리소스에 대한 스레드 액세스 동기화

docs.microsoft.com

 

 

★☆

 

반응형

댓글