2014-06-14 6 views
0

코드에서 정적 요소 (잠금을 사용하여)를 설정하거나 가져 오는 코드의 여러 세그먼트에 대한 질문이 있습니다.스레드 안전 C#

그래서이 코드가 맞습니까? 그리고 한 순간에 MethodB와 MethodC를 호출하면 어떻게됩니까? 사실, 그들은 한 순간에 하나의 정적 메서드를 호출합니다 (다른 lock() 세그먼트에서). 안전합니까?

public class ThreadsClass 
{ 
    public static class StaticHelper 
    { 
     public static string NameStatic { get; set; } 

     public static void MethodCountStatic(int num) 
     { 
      for (int i = 0; i <= num; i++) 
      { 
       Console.WriteLine("{0} step...",i); 
      } 
     } 
    } 

    private Object lockObject = new Object(); 

    public void MethodA() 
    { 
     lock (lockObject) 
     { 
      StaticHelper.NameStatic = "somename"; 
     } 
    } 

    public void MethodB() 
    { 
     lock (lockObject) 
     { 
      StaticHelper.MethodCountStatic(1000000); 
     }   
    } 

    public void MethodC() 
    { 
     lock (lockObject) 
     { 
      StaticHelper.MethodCountStatic(500000000); 
     } 
    } 
} 
+1

무엇을 수정합니까? 판타지 코드이며 환상적인 시나리오에서 작동합니다. 그리고 다른 곳에서는 실패 할 것입니다. –

답변

2

음, 그렇습니다.

코드의 현재 상태에서 MethodCountStatic은 상태를 유지하지 않으므로 스레드 안전성이 있으며 아무 것도 읽지 않으므로 NameStatic을 읽지 않습니다. 항상 그런 것은 아니라고 생각합니다.

코드를 작성하면 최소한 두 가지 문제가 있습니다.

  • StaticHelper 그렇게 모든 클래스 어떤 메서드를 호출하거나 잠금없이 임의의 속성에 액세스 할 수 있습니다, public입니다.

  • ThreadsClass의 인스턴스 두 개를 만들면 두 개의 서로 다른 잠금이 있으므로 서로의 잠금을 보지 않고 StaticClass의 속성을 호출하거나 액세스 할 수 없습니다. 이 클래스는 스레드로부터 안전합니다

, 당신은이 문제를 극복하기 위해 민간 StaticHelperlockObject 정적 확인해야합니다.

편집 : StaticHelper를 공개하고 상태를 유지하려면, 대신 클래스 자체의 잠금을 해제하는 것이 좋습니다.

public static class StaticHelper 
{ 
    private static Object lockObject = new Object(); 
    private static string _nameStatic; 

    public static string NameStatic { 
     get { lock (lockObject) return _nameStatic; } 
     set { lock (lockObject) _nameStatic = value; } 
    } 

    public static void MethodCountStatic(int num) { 
     lock (lockObject) { 
      // Your method here... 
     } 
    } 
} 

그런 식으로, 관련없는 많은 클래스에 퍼지기보다 잠금이 필요한 클래스로 격리됩니다.

+0

Joachim Isaksson, 답장을 위해 thx! 하지만 StaticHelper 전역 정적 클래스를 만들고 내 응용 프로그램의 모든 장소 (및 다른 스레드)의 메서드 및 속성에 안전 액세스를 제공하려면 어떻게해야합니까? 그러한 기능을 제공 할 수있는 기회가 있습니까? – NETRY

+0

@ user3648230 그에 대한 편집을 추가했습니다. –

+0

고마워요! 그리고 그것은 문제가되지 않습니다, 내 정적 메서드의 매개 변수 [int num]은 다른 호출에서 다를 수 있습니까? 예를 들어 한 순간에 2 개의 스레드가 MethodCountStatic (100) 및 MethodCountStatic (200)을 호출하면 어떻게됩니까? – NETRY

0

예, 현재의 경우 방법 MethodB에 대한 기능은 MethodC 스레드 안전 аnd. 그러나이 메서드를 무시하고 정적 클래스의 public 멤버에 액세스 할 수 있습니다.