프로그래밍/.NET2012. 10. 29. 17:17

Monitor 클래스는 하나의 스레드에 개체 잠금을 부여하여 개체에 대한 액세스를 제어합니다. 개체 잠금 기능을 사용하면 일반적으로 임계 영역이라고 불리는 코드 블록에 대한 액세스를 제한할 수 있습니다. 한 스레드에서 개체 잠금을 소유하는 동안에는 다른 스레드에서 해당 잠금을 가져올 수 없습니다. 다른 스레드에서 잠겨 있는 다른 개체를 사용하여 코드를 실행하는 경우에만 Monitor를 사용하여 다른 스레드에서 잠금 소유자가 실행하고 있는 응용 프로그램 코드의 섹션에 액세스할 수 있도록 할 수도 있습니다.


메서드

모든 메서드가 Static

 이름

설명 

 Enter

 지정된 개체의 단독 잠금을 가져옵니다.

 Exit 

 지정된 개체의 단독 잠금을 해제합니다. 

 Pulse 

 대기 중인 큐에 포함된 스레드에 잠겨 있는 개체의 상태 변경을 알립니다. 

 PulseAll 

 대기 중인 모든 스레드에 개체 상태 변경을 알립니다. 

 TryEnter 

 지정된 개체의 단독 잠금을 가져오려고 합니다. 

 Wait 

 개체의 잠금을 해제한 다음 잠금을 다시 가져올 때까지 현재 스레드를 차단합니다. 


예제

콘솔 응용 프로그램 프로젝트를 만듭니다.

Program.cs

using System;
using System.Linq;
using System.Text;
using System.Threading;

namespace MonitorClass
{
    class Program
    {
        static void Main(string[] args)
        {
            Threading T = new Threading();
        }
    }

    class Threading
    {
        private int count = 0;

        public Threading()
        {

            Thread T1 = new Thread(new ThreadStart(Work));
            Thread T2 = new Thread(new ThreadStart(Work));
            Thread T3 = new Thread(new ThreadStart(Work));

            T1.Start();
            T2.Start();
            T3.Start();
        }

        private void Work()
        {
            for (int i = 0; i < 5; i++)
            {
                Console.WriteLine(count++);
            }
        }
    }
}

그리고 실행을 시켜봅니다.


결과가 조금 엉망입니다. count가 여러 스레드에서 무분별하게 액세스 되었기 때문입니다.

그럼 이제 Monitor Class를 이용하여 액세스를 제어해봅시다.


Program.cs(Monitor Class)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace MonitorClass
{
    class Program
    {
        static void Main(string[] args)
        {
            Threading T = new Threading();
        }
    }

    class Threading
    {
        private int count = 0;

        public Threading()
        {

            Thread T1 = new Thread(new ThreadStart(Work));
            Thread T2 = new Thread(new ThreadStart(Work));
            Thread T3 = new Thread(new ThreadStart(Work));

            T1.Start();
            T2.Start();
            T3.Start();
        }

        private void Work()
        {
            Monitor.Enter(this);

            for (int i = 0; i < 5; i++)
            {
                Console.WriteLine(count++);
            }

            Monitor.Exit(this);
        }
    }
}

그리고 실행을 해봅시다.


아까하고는 다른 결과물이 나왔습니다.

하나의 스레드가 액세스 할 동안 다른 스레드는 대기를 하기 때문에 입니다.

Monitor 클래스는 스레드의 "교착 상태"를 해결해주는 역활을 합니다.



Posted by 건깡