C#의 멀티스레딩 메커니즘에 대한 예비 연구(4)

黄舟
풀어 주다: 2016-12-21 15:02:03
원래의
1098명이 탐색했습니다.

exPRession은 추적하려는 개체(일반적으로 개체 참조)를 나타냅니다. 일반적으로 클래스의 인스턴스를 보호하려면 이것을 사용할 수 있습니다. 정적 변수(예: 정적 메서드 내의 상호 배타적 코드 세그먼트)를 보호하려면 일반적으로 클래스 이름을 사용합니다. state_block은 상호 배타적인 섹션의 코드입니다. 이 코드는 한 번에 하나의 스레드에서만 실행될 수 있습니다.

다음은 lock 키워드를 사용하는 일반적인 예입니다. 댓글에서 lock 키워드의 사용법과 목적을 설명하겠습니다.

//lock.cs
 시스템 사용; = new Random();
내부 계정(int 초기)

{

 = 초기; }

internal int Withdraw(int amount)
{
if (balance < 0)
 {
//잔액이 0보다 작은 경우 예외를 발생시킵니다.
throw new Exception("Negative Balance")

 }

//다음 코드는 현재 스레드가 잔액 값 수정을 완료하기 전에
//다른 스레드가 이를 실행하지 않도록 합니다. 잔액 값을 수정하는 코드
//따라서 잔액 값은 0보다 작을 수 없습니다.
lock (this)
{
 Console.WriteLine("Current Thread:"+Thread.CurrentThread.Name);
//lock 키워드로 보호되지 않는 경우 ,
//다른 스레드가 잔액=잔액-금액을 실행하고 잔액 값을 수정한 경우
 조건을 판단한 후 실행될 수 있습니다. //그리고 이 수정 사항은 이 스레드에 표시되지 않으므로 현재로서는 if 조건이 더 이상 유지되지 않을 수 있습니다.
//그러나 이 스레드는 계속해서 Balance=balance-amount를 실행하므로 잔액은 0보다 작을 수 있습니다.
(잔액 >= 금액)
{
 Thread.Sleep(5 );
balance = 잔액 - 금액 🎜>else

return 0; // 거래 ​​거부됨  }
}
}
 internal void DoTransactions()
{  for (int i = 0; i Withdraw(r.Next( -50, 100));
}
}

내부 클래스 테스트
{
정적 내부 스레드[] 스레드 = 새 스레드[10]
public static void Main()
{
계정 계정 = 새 계정(0); for (int i = 0; i {
Thread t = new Thread(new ThreadStart( acc.DoTransactions))
 스레드[i] = t;
}
for (int i = 0; i  threads[i].Name=i.ToString()

for (int i = 0; 10; i++)
threads[ i].Start()
Console.ReadLine()
} }

여러 스레드가 객체를 공유하는 경우 공개 코드와 유사한 문제도 발생합니다. 이러한 종류의 문제에는 lock 키워드를 사용하면 안 됩니다. System.Threading. 모니터는 스레드가 리소스 계획을 공유하는 방법을 제공합니다.

Monitor 클래스는 객체를 잠글 수 있습니다. 스레드는 잠금을 획득한 경우에만 객체에 대해 작업을 수행할 수 있습니다. 개체 잠금 메커니즘은 혼란을 야기할 수 있는 상황에서 한 번에 하나의 스레드만 이 개체에 액세스할 수 있도록 보장합니다. 모니터는 특정 객체와 연결되어야 하지만 정적 클래스이기 때문에 객체를 정의하는 데 사용할 수 없으며, 해당 메서드도 모두 정적이므로 객체를 사용하여 참조할 수 없습니다. 다음 코드는 Monitor를 사용하여 객체를 잠그는 방법을 보여줍니다.

......
Queue oQueue=new Queue()
..... .
Monitor.Enter(oQueue);
......//이제 oQueue 객체는 현재 스레드로만 조작할 수 있습니다.
Monitor.Exit(oQueue); //잠금 해제

위에 표시된 것처럼 스레드가 개체를 잠그기 위해 Monitor.Enter() 메서드를 호출하면 개체는 해당 개체의 소유가 됩니다. 다른 스레드가 이 개체에 액세스하려는 경우 해당 개체가 해당 개체를 사용할 때까지 기다려야 합니다. Monitor.Exit() 메서드 잠금을 해제합니다. 스레드가 결국 잠금을 해제하도록 하려면 try-catch-finally 구조의 finally 코드 블록에 Monitor.Exit() 메서드를 작성할 수 있습니다. 모니터에 의해 잠긴 개체의 경우 이와 관련된 일부 정보가 메모리에 저장됩니다. 하나는 현재 잠금을 보유하고 있는 스레드에 대한 참조이고, 다른 하나는 잠금을 획득할 준비가 된 개체를 저장하는 준비 대기열입니다. 세 번째 스레드는 현재 객체의 상태가 변경되기를 기다리고 있는 큐에 대한 참조를 보유하는 대기 큐입니다. 개체 잠금을 소유한 스레드가 잠금을 해제할 준비가 되면 Monitor.Pulse() 메서드를 사용하여 대기 대기열의 첫 번째 스레드에 알리므로 개체 잠금이 해제되면 스레드가 준비 대기열로 전송됩니다. , 준비 대기열에서 스레드는 즉시 개체 잠금을 획득할 수 있습니다.

다음은 스레드 동기화 및 통신을 달성하기 위해 lock 키워드와 Monitor 클래스를 사용하는 방법을 보여주는 예입니다. 이는 또한 일반적인 생산자 및 소비자 문제이기도 합니다. 이 루틴에서는 생산자 스레드와 소비자 스레드가 번갈아 가며 숫자를 쓰고, 소비자는 이를 즉시 읽고 표시해 줍니다. 사용된 시스템 네임스페이스는 다음과 같습니다.

using System;
using System.Threading

위는 C#의 멀티스레딩 메커니즘(4)의 내용입니다. 관련 내용은 PHP 중국어 홈페이지(www.php.cn)를 참고해주세요!


관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!