... | ... | @@ -1371,3 +1371,76 @@ class MonitorEx2 |
|
|
}
|
|
|
}
|
|
|
```
|
|
|
|
|
|
대부분의 BCL 정적 멤버는 다중 스레드 접근에 안전하다. 하지만 인스턴스 멤버는 다중 스레드로 접근했을 때 안전하지 않다. 모든 멤버에 lock을 걸면 다중 스레드 접근에는 안전해지지만, 성능 상의 문제가 발생할 수 있다. 대부분의 경우는 단일 스레드에서만 접근하기 때문에 lock 보호 장치를 걸지 않았고, 동기화가 필요한 경우에는 직접 처리해야 한다.
|
|
|
|
|
|
lock 보호 장치 유무에 따른 속도 비교
|
|
|
|
|
|
```c#
|
|
|
class MonitorEx3
|
|
|
{
|
|
|
|
|
|
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);
|
|
|
}
|
|
|
|
|
|
class MyData
|
|
|
{
|
|
|
|
|
|
int number = 0;
|
|
|
|
|
|
public object _numberLock = new object(); //임의의 object 객체를 lock을 위해 만들어준다.
|
|
|
|
|
|
public int Number { get => number; }
|
|
|
|
|
|
public void Increment()
|
|
|
{
|
|
|
number++;
|
|
|
}
|
|
|
|
|
|
public void IncrementLock()
|
|
|
{
|
|
|
lock (_numberLock)
|
|
|
{
|
|
|
number++;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
static void ThreadFunc(object inst)
|
|
|
{
|
|
|
MyData data = inst as MyData;
|
|
|
|
|
|
Stopwatch st = new Stopwatch();
|
|
|
|
|
|
st.Start();
|
|
|
for (int i = 0; i < 100000; i++)
|
|
|
{
|
|
|
data.Increment();
|
|
|
}
|
|
|
st.Stop();
|
|
|
Console.WriteLine("lock을 쓰지 않았을 때의 시간 : {0} Ticks", st.Elapsed.Ticks);
|
|
|
|
|
|
st.Start();
|
|
|
for (int i = 0; i < 100000; i++)
|
|
|
{
|
|
|
data.IncrementLock();
|
|
|
}
|
|
|
st.Stop();
|
|
|
Console.WriteLine("lock을 썼을 때의 시간 : {0} Ticks", st.Elapsed.Ticks); //일반적으로 다섯 배 이상 차이가 난다.
|
|
|
|
|
|
}
|
|
|
}
|
|
|
``` |