C#의 Java와 같은 스레드 동기화
-
06-07-2019 - |
문제
저는 Java 프로그래머이며 Java를 스레딩하는 것에 대해 몇 가지를 알고 있습니다.
Java에서는 동기화 된 키워드를 사용하여 메소드를 잠글 수 있습니다.
private int a;
private int b;
private int c;
private synchronized void changeVars()
{
a = 4;
b = 2;
c = a+b;
}
나는 MSDN에서 검색했고 C#에는 스레드와 함께 연주 할 장난감이 몇 개 있다는 것을 보았다. 예를 들어 Monitor.enter, Monitor.exit, Lock 또는 고급 뮤트 텍스와 같은.
그러나 내가 필요한 것은 하나의 방법을 동기화하는 것입니다. C#의 동등한 것은 무엇입니까?
미리 감사드립니다.
해결책
이 신체와 같은 것 :
using System.Runtime.CompilerServices;
...
private int a;
private int b;
private int c;
[MethodImpl(MethodImplOptions.Synchronized)]
private void changeVars()
{
a = 4;
b = 2;
c = a+b;
}
다른 팁
C#에는 직접적인 동등한 것이 없지만 다음과 같은 작업을 수행 할 수 있습니다.
private readonly object changeVarsLockObject = new object();
private void changeVars()
{
lock(changeVarsLockObject)
{
a = 4;
b = 2;
c = a+b;
}
}
명확하게 말하면 - Java에서 동기화 된 메소드를 선언하려면 발신자가 모니터를 보유해야합니다. 물체 방법이 호출되었다는 (이것은 Class
정적 방법에 대한 객체).
따라서 "메소드 잠금"을 할 수 있다고 말하면 해당 메소드를 완전히 잠그지 않기 때문에 오해의 소지가 있습니다 (동일한 메소드는 여전히 다른 인스턴스 개체에서 호출 될 수 있음). 더 그 방법 (다른 동기화 된 메소드 또는 명시 적 획득을 포함하여 대상 객체의 모니터가 필요한 다른 코드는 동시에 실행될 수 있습니다).
동기화는 어렵습니다, 그리고 이상적으로는 테스트 중에 거의 나타나지 않거나 디버깅에 도움이되는 교착 상태와 가시성 문제를 피하려면 "몇 가지"이상을 알아야합니다. 한 언어로 동기화를 불완전하게 이해하고 다른 프리미티브와 다른 메모리 모델을 사용하여 다른 언어로 전달하려고 시도하는 것은 재난의 레시피 일 것입니다.
그래서 이것이 당신이 찾고 있던 1 라이너 답변은 아니지만, 나는 전체 생태계에 대한 지식없이 그것을 뒷받침 할 수있는 하나의 라이너 답변이 실패했다고 주장 할 것입니다. 따라서 당신은해야합니다 좋은 책/튜토리얼을 읽으십시오 C#의 동기화에 따라 Java Experience Keyword를 키워드별로 변환하려고 시도하지 않습니다.
그것의 직접 동등한 것은 잠금 (this)을 사용하는 것입니다.
private void ChangeVars()
{
lock (this) {
a = 4;
b = 2;
c = a+b;
}
}
또는 실제로 R. Bemrose가 기술 한 Methodimplattribute를 사용하는데, 이는 동일한 것과 관련이 있습니다.
[MethodImpl(MethodImplOptions.Synchronized)]
private void ChangeVars()
{
a = 4;
b = 2;
c = a+b;
}
... 그러나 다른 사람이 잠금 객체로 사용하기로 결정할 수 있으므로 더 나은 번역은 다음과 같습니다.
private object monitor = new object();
private void ChangeVars()
{
lock (monitor) {
a = 4;
b = 2;
c = a+b;
}
}
선호되는 솔루션은 메소드 본문을 lock
성명.
internal class Foo
{
private Object lockObject = new Object();
private void ChangeVars()
{
lock (this.lockObject)
{
// Manipulate the state.
}
}
}
당신은 선언적 동기화를 사용할 수 있지만, 이것은 당신이 파생해야 할 명백한 단점이 있습니다. ContextBoundObject
그리고 모든 방법으로 장식되어 있습니다 Synchronization
속성 잠금 세분성을 제한하는 동일한 잠금 객체를 공유합니다.
internal class Foo : ContextBoundObject
{
[Synchronization]
private void ChangeVars()
{
// Manipulate the state.
}
}