>  기사  >  백엔드 개발  >  C# 스레드 동기화 및 스레드 풀 간략한 분석

C# 스레드 동기화 및 스레드 풀 간략한 분석

黄舟
黄舟원래의
2017-03-03 13:34:491263검색

C# 스레드 동기화 및 스레드 풀

예제는 매우 간단합니다. 5개의 스레드를 준비하고, 각 스레드는 동시에 콘솔에 숫자를 출력하고, 그런 다음 출력 결과를 관찰하십시오.

코드 설명:

////스레드 목록

private static List<Thread> _threadList;
 
 
        static voidMain(string[] args)
        {
            Program._threadList= new List<Thread>();
            ////附加5个线程
            for (inti = 0; i < 5; i++)
            {
                Program.AppendThread();
            }
 
            ////开始执行所有测试线程
            Program.ExecuteThread();
 
            ////按任意键退出
            Console.ReadLine();
        }
 
        /// <summary>
        /// 将新的测试线程附加到测试线程列表,线程执行逻辑就是输出10个数字
/// 注意初始化的时候设置为后台线程了,这样可以保证主线程退出的时候其他线/// 程自动退出
        /// </summary>
        public staticvoid AppendThread()
        {
            Program._threadList.Add(newThread(new ThreadStart(
                () =>
                {
                   for (int i = 0; i < 10; i++)
                   {
                       Console.WriteLine(i);
                   }
                })){ IsBackground = true });
        }
 
        /// <summary>
        /// 开始执行所有测试线程
        /// </summary>
        public staticvoid ExecuteThread()
        {
            foreach(Thread t in _threadList)
            {
                t.Start();
            }
        }

실행 결과를 보면 다음과 같은 결과가 나오는 것을 알 수 있습니다.

결과에 따르면(숫자의 출력이 불규칙함) 스레드 사이에 간섭이 발생한 것을 알 수 있습니다. 전략은 스레드 동기화를 위한 동기화 멤버를 추가하는 것입니다:

   /// <summary>
        /// 多线程同步的对象
        /// </summary>
        private static object _syncObj = new object();
另外,在线程执行的地方加锁:
Program._threadList.Add(newThread(new ThreadStart(
                () =>
                {
                    lock (_syncObj)
                    {
                        for (int i = 0; i < 10;i++)
                        {
                            Console.WriteLine(i);
                        }
                    }
 
                })) { IsBackground = true });

관찰 결과:


당신 Lock 키워드를 통해 다중 스레드 동기화 변수를 잠그면 실제로 스레드를 동기화할 수 있음을 알 수 있습니다.

이제 두 번째 방법을 살펴보세요.

동기화를 위해 모니터 키워드를 사용하세요. 코드:

Monitor.Enter(_syncObj);
                   try
                   {
                       for (int i = 0; i < 10; i++)
                       {
                            Console.WriteLine(i);
                       }
                   }
                   finally {
                       Monitor.Exit(_syncObj);
                   }

결과를 보면 스레드가 동기화된 것을 확인할 수 있습니다.


세 번째 방법:

이제 코드를 리팩터링하고, 새 ThreadManager 클래스를 생성하고, 클래스의 모든 책임을 그 클래스로 옮겨 보겠습니다.

class ThreadManager
    {
        /// <summary>
        /// 线程列表
        /// </summary>
        private staticList<Thread> _threadList;
 
        staticThreadManager()
        {
           _threadList = new List<Thread>();
        }
 
        /// <summary>
        /// 附加新线程
        /// </summary>
        public staticvoid AppendThread()
        {
            ThreadManager._threadList.Add(newThread(new ThreadStart(
                () =>
                {
                   for (int i = 0; i < 10; i++)
                   {
                       Console.WriteLine(i);
                   }
 
                })){ IsBackground = true });
        }
 
        /// <summary>
        /// 开始执行所有线程
        /// </summary>
        public staticvoid ExecuteThread()
        {
            foreach(Thread t in _threadList)
            {
                t.Start();
            }
        }
    }

Main 함수에서 호출한 코드를 해당 변경합니다:

static voidMain(string[] args)
        {
            ////附加5个线程
            for (int i = 0; i < 5; i++)
            {
                ThreadManager.AppendThread();
            }
 
            ////开始测试
            ThreadManager.ExecuteThread();
 
            ////按任意键继续
            Console.ReadLine();
        }

스레드 동기화에 대한 처리가 수행되지 않으므로 결과는 스레드가 비동기적이라고 확실히 추측할 수 있습니다.


이제

ThreadManager 클래스에 기능을 추가하세요: [동기화] 및 다시 실행하십시오. 이것은 스레드 동기화를 위한 네 번째 솔루션입니다. 사용하기는 매우 간단하지만 먼저 실행 로직을 클래스에 배치해야 합니다. 이 클래스의 모든 메소드가 스레드로부터 안전한지 확인하여 성능이 상대적으로 비효율적입니다. 스레드를 동기화하는 방법이 있나요? 대답은 '예'입니다. 이는 네 번째 메소드 스레드 풀입니다.

이제 스레드 풀을 사용하여 구현하는 방법을 살펴보겠습니다.

  static void Main(string[]args)
        {
/////定义一个waitCallback对象,并定义它的行为,就是向控制台输出十个数字同时可以传递/////一个参数(这个参数是可选的)
                       WaitCallback work = new WaitCallback((o)=>
            {
                for(int i = 0; i < 10; i++)
                {
                   Console.WriteLine(i);
                }
            });
 
            ////执行5次
            for (inti = 0; i < 5; i++)
            {
/////如果这里需要传递参数,可以调用另一个重载方法
                ThreadPool.QueueUserWorkItem(work);
            }
 
            ////按任意键继续
            Console.ReadLine();
        }

이제 논리가 완성되었나요? 예, 실행 후 결과를 볼 수 있습니다. 스레드가 동기화되었습니다.

멀티스레딩은 또 어떤 이점을 제공하나요?

    스레드 풀을 사용하면 스레드 생성, 시작 및 중지 횟수가 줄어들어 효율성이 향상됩니다.
  • 스레드 풀을 사용하면 비즈니스에 집중할 수 있습니다. 멀티 스레드 아키텍처보다는 로직(단, 경우에 따라 수동 스레드 관리가 선호되어야 함)
  • 포그라운드 스레드가 필요하거나 우선 순위 수준을 설정하거나 스레드 풀을 설정하는 경우 스레드 in은 항상 백그라운드 스레드이고 해당 우선순위는 기본값입니다.
  • 이름으로 종료, 일시 중지 또는 검색을 용이하게 하기 위해 고정된 ID가 있는 스레드가 필요한 경우.

위 내용은 C# 스레드 동기화 및 스레드 풀에 대한 간략한 분석입니다. CN)!


성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.