본문 바로가기
개발/기본) 기본기

기본기)Lazy <T> 클래스

by 테샤르 2021. 1. 7.

Lazy <T> 클래스

 

쓰레드에서  종종 보이는 클래스로 '지연 생성'을 하는 클래스를 말한다.

지연 생성이라는 건. 이미 생성이 아닌 접근(Acees)하는 순간 생성하는 것을 말한다. 

 

사용하는 곳은 다음과 같다.

 

1.리소스를 많이 사용해서 실행하는 순간 생성으로 인한 성능 향상이 필요한 경우에 사용

(웹사이트)등에 기술 최적화에 많이 사용된다.)

2.무한 스크롤 같은 부분로딩하는 과정

3.멀티 쓰레드에서 싱글톤의 데이터에 안전하게 생성해야 하는 경우에 사용

반응형

예제 코드를 보연 다음과 같다. Doc의 예제 코드이다.

using System;
using System.Threading;

class Program
{
    static Lazy<LargeObject> lazyLargeObject = null;

    static LargeObject InitLargeObject()
    {
        LargeObject large = new LargeObject(Thread.CurrentThread.ManagedThreadId);
        // Perform additional initialization here.
        return large;
    }

    static void Main()
    {
        // The lazy initializer is created here. LargeObject is not created until the
        // ThreadProc method executes.
        lazyLargeObject = new Lazy<LargeObject>(InitLargeObject);

        // The following lines show how to use other constructors to achieve exactly the
        // same result as the previous line:
        //lazyLargeObject = new Lazy<LargeObject>(InitLargeObject, true);
        //lazyLargeObject = new Lazy<LargeObject>(InitLargeObject,
        //                               LazyThreadSafetyMode.ExecutionAndPublication);

        Console.WriteLine(
            "\r\nLargeObject is not created until you access the Value property of the lazy" +
            "\r\ninitializer. Press Enter to create LargeObject.");
        Console.ReadLine();

        // Create and start 3 threads, each of which uses LargeObject.
        Thread[] threads = new Thread[3];
        for (int i = 0; i < 3; i++)
        {
            threads[i] = new Thread(ThreadProc);
            threads[i].Start();
        }

        // Wait for all 3 threads to finish.
        foreach (Thread t in threads)
        {
            t.Join();
        }

        Console.WriteLine("\r\nPress Enter to end the program");
        Console.ReadLine();
    }

    static void ThreadProc(object state)
    {
        LargeObject large = lazyLargeObject.Value;

        // IMPORTANT: Lazy initialization is thread-safe, but it doesn't protect the
        //            object after creation. You must lock the object before accessing it,
        //            unless the type is thread safe. (LargeObject is not thread safe.)
        lock(large)
        {
            large.Data[0] = Thread.CurrentThread.ManagedThreadId;
            Console.WriteLine("Initialized by thread {0}; last used by thread {1}.",
                large.InitializedBy, large.Data[0]);
        }
    }
}

class LargeObject
{
    public int InitializedBy { get { return initBy; } }

    int initBy = 0;
    public LargeObject(int initializedBy)
    {
        initBy = initializedBy;
        Console.WriteLine("LargeObject was created on thread id {0}.", initBy);
    }

    public long[] Data = new long[100000000];
}

/* This example produces output similar to the following:

LargeObject is not created until you access the Value property of the lazy
initializer. Press Enter to create LargeObject.

LargeObject was created on thread id 3.
Initialized by thread 3; last used by thread 3.
Initialized by thread 3; last used by thread 4.
Initialized by thread 3; last used by thread 5.

Press Enter to end the program
 */

Main에서 3개의 Thread가 생성되면서 ThreadProc을 실행하는데 그 과정에서 Lazy로 생성된 LargeObject.Value를 접근하는 순간 해당 오브젝트에 대한 생성자를 불리는 것을 알 수 있다.

 

결론적으로는 각자 병행해서 처리하는 과정에서 안전하게 값을 생성하는 것을 만들 수 있다.

 

Microsoft Doc : [링크]

 

Lazy 클래스 (System)

초기화 지연에 대한 지원을 제공합니다.Provides support for lazy initialization.

docs.microsoft.com

 

★☆

 

반응형

댓글