... | ... | @@ -1296,6 +1296,7 @@ class MonitorEx1 |
|
|
//모니터 Enter와 Exit 사이의 코드는 한 순간에 스레드 하나에만 진입해서 실행된다.
|
|
|
//Enter와 Exit 메서드로 전달하는 인자는 참조형 타입의 인스턴스여야 한다.
|
|
|
//me객체의 잠금이 한 스레드에 점유되고 있으면 다른 스레드는 me 객체에 대한 작업을 하지 못하고 대기 상태로 들어간다.
|
|
|
//값 타입을 매개변수로 넣으면 System.Threading.SynchronizationLockException: 예외 출력.
|
|
|
|
|
|
try
|
|
|
{
|
... | ... | @@ -1317,3 +1318,56 @@ class MonitorEx1 |
|
|
}
|
|
|
}
|
|
|
```
|
|
|
|
|
|
안전하지 않은 메서드
|
|
|
|
|
|
```c#
|
|
|
class MyData
|
|
|
{
|
|
|
int number = 0;
|
|
|
|
|
|
//public object _numberLock = new object(); //임의의 object 객체를 lock을 위해 만들어준다.
|
|
|
|
|
|
public int Number { get => number; }
|
|
|
|
|
|
public void Increment()
|
|
|
{
|
|
|
//이 메서드에 아무런 동기화 기능도 제공하지 않았다.이를 스레드에 안전하지 않은 메서드라고 한다.
|
|
|
number++;
|
|
|
|
|
|
//lock(_numberLock) //메서드 내부에서는 동기화 처리를 이렇게 할 수 있다.
|
|
|
//{
|
|
|
// number++;
|
|
|
//}
|
|
|
}
|
|
|
}
|
|
|
class MonitorEx2
|
|
|
{
|
|
|
public static void Main()
|
|
|
{
|
|
|
MyData data = new MyData();
|
|
|
|
|
|
Thread t1 = new Thread(ThreadFunc);
|
|
|
Thread t2 = new Thread(ThreadFunc);
|
|
|
|
|
|
t1.Start(data);
|
|
|
t2.Start(data);
|
|
|
|
|
|
t1.Join();
|
|
|
t2.Join();
|
|
|
|
|
|
Console.WriteLine(data.Number);
|
|
|
}
|
|
|
|
|
|
static void ThreadFunc(object inst)
|
|
|
{
|
|
|
MyData data = inst as MyData;
|
|
|
|
|
|
for ( int i = 0; i < 100000; i++)
|
|
|
{
|
|
|
//lock(data) { data.Increment(); } 안전하지 않은 메서드에 대한 외부 동기화 처리
|
|
|
data.Increment();
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
``` |