IT TIP

정적 메서드는 스레드로부터 안전합니까?

itqueen 2020. 12. 29. 08:11
반응형

정적 메서드는 스레드로부터 안전합니까?


각 페이지를 구성하는 데 걸린 시간을 계산하기 위해 모든 웹 페이지에서 호출 할 정적 타이머 클래스가 있습니다.

내 질문은 정적 클래스 스레드로부터 안전합니까? 내 예에서 동시 사용자가 시작 및 중지 시간에 문제를 일으킬 수 있습니까? 예를 들어 다른 스레드가 내 시작 및 중지 값을 덮어 씁니다.

public static class Timer
{
    private static DateTime _startTime;
    private static DateTime _stopTime;    

    /// <summary>
    /// Gets the amount of time taken in milliseconds
    /// </summary>
    /// <returns></returns>
    public static decimal Duration()
    {
        TimeSpan duration =  _stopTime - _startTime;
        return duration.Milliseconds;
    }

    public static void Start()
    {
        _startTime = DateTime.Now;
    }

    public static void Stop()
    {
        _stopTime = DateTime.Now;
    }
}

이 클래스는 비 정적 클래스 여야합니까?

(이 클래스는 asp.net 마스터 페이지에서 호출됩니다.)


정적 메서드는 본질적으로 스레드로부터 안전 하지 않습니다 . CLR에서는 인스턴스 메서드와 다르게 처리되지 않습니다. 차이점은 일반적으로 스레드로부터 안전 하도록 만들어야 한다는 것입니다. (스레드로부터 안전하지 않은 .NET BCL 정적 메서드는 생각할 수 없습니다.) 일반적인 패턴은 객체를 생성하고 한 스레드에서 반복적으로 사용하는 것이기 때문에 인스턴스 메서드는 스레드로부터 안전하지 않습니다. 않는 여러 스레드에서 사용할 수 있고, 합동 개체가 안전하게 사용할되어 있는지 확인하고 포함하고있었습니다. 대부분의 경우 개체 자체보다 조정 코드에서 수행하는 것이 더 적절합니다. (일반적으로 전체 작업 시퀀스를 효과적으로 원자 단위로 만들고 싶습니다. 객체 내에서 수행 할 수없는 작업입니다.)

귀하의 Timer클래스는 thread 세이프가 가장 확실히되지 않습니다 : 두 개의 스레드가 쉽게 서로의 데이터를 짓밟 수 있으며, 기간을 계산할 때 "오래된"데이터를 사용하는 스레드를 중지 아무것도 없다.

Stopwatch대신 클래스를 사용하십시오 -그것이 거기에있는 이유입니다. 여러 스레드에서 하나의 인스턴스를 사용하려면 안전을 보장하기 위해 정상적인 단계를 수행해야하지만 일반적으로 훨씬 더 나은 위치에있게됩니다. 물론 Stopwatch완벽 하지도 않습니다. 자세한 내용 이 질문 과 아래의 설명을 참조하세요.하지만 적어도 유형이 설계된 대상입니다. (누가 알다시피, 언젠가 고쳐질지도 ...)


여기에는 예제가 스레드로부터 안전하지 않은 이유와 메커니즘에 더 초점을 맞춘 좋은 토론이 있습니다 .

요약하면, 먼저 정적 변수가 공유됩니다. 로컬 변수로 만들 수 있다면 정적 메서드에 로컬이더라도 여전히 자체 스택 프레임을 얻으므로 스레드로부터 안전합니다. 또한 정적 변수 (즉,이 스레드의 다른 사용자가 언급 한 잠금 및 / 또는 기타 다중 스레드 프로그래밍 기술)를 보호하는 경우 샘플 정적 클래스를 스레드로부터 안전하게 만들 수도 있습니다.

둘째, 귀하의 예제는 사용자가 수정하거나 다른 스레드가 상태를 처리 할 수있는 외부 변수 인스턴스를 사용하지 않기 때문에 해당 예제도 스레드로부터 안전합니다.


타이머 클래스는 확실히 스레드로부터 안전하지 않습니다. 시간을 측정해야 할 때마다 일반 클래스를 만들고 인스턴스화해야합니다.

Timer timer = new Timer();

timer.Start();
//...
timer.Stop();

decimal duration = timer.Duration();

더 좋은 점은 다음과 같은 작업을 수행하는 기본 제공 .NET 클래스입니다.

Stopwatch sw = Stopwatch.StartNew();

sw.Stop();

TimeSpan duration = sw.Elapsed;

예, 맞습니다.이 클래스의 정적 멤버 / 접근자는 다른 사용자가 해당 멤버를 덮어 쓰게합니다.

이것이 인스턴스와 비 정적 멤버가있는 이유입니다.

참조 URL : https://stackoverflow.com/questions/1090650/are-static-methods-thread-safe

반응형