C# 線程使用

來源:互聯網
上載者:User

1.lock鎖定

 建立一個類,代碼如下:

View Code

class Person
{
private readonly int RunCount = 10000;
private int RunCountA = 0;//A方法執行的次數
private int RunCountB = 0;//B方法執行的次數
private int RunCountC = 0;//總共方法執行的次數
private bool IsRunA = true;
public void DoWorkA() {
Console.WriteLine("DoWorkA...");
while (true)
{
if (RunCountA == RunCount || RunCountB == RunCount)
{
Console.WriteLine("DoWorkA:RunCountA:{0} RunCountB:{1} RunCountC:{2}", RunCountA, RunCountB, RunCountC);
break;
}
//lock (o)
//{
if (IsRunA)
{
RunCountA++;
RunCountC++;
IsRunA = !IsRunA;
}
//}

}
}
public void DoWorkB()
{
Console.WriteLine("DoWorkB...");
while (true)
{
if (RunCountA == RunCount || RunCountB == RunCount)
{
Console.WriteLine("DoWorkB:RunCountA:{0} RunCountB:{1} RunCountC:{2}", RunCountA, RunCountB, RunCountC);
break;
}
//lock (o)
//{
if (!IsRunA)
{
RunCountB++;
RunCountC++;
IsRunA = !IsRunA;
}
//}

}
}

private object o=new object();
}

調用代碼如下:

     static void Main(string[] args)
{
Person p = new Person();
System.Threading.Thread t1 = new System.Threading.Thread(new System.Threading.ThreadStart(p.DoWorkA));
System.Threading.Thread t2 = new System.Threading.Thread(new System.Threading.ThreadStart(p.DoWorkB));
System.Threading.Thread t3 = new System.Threading.Thread(new System.Threading.ThreadStart(p.DoWorkB));
t3.Start();
System.Threading.Thread t4 = new System.Threading.Thread(new System.Threading.ThreadStart(p.DoWorkB));
t4.Start();
t1.Start();
t2.Start();
Console.ReadLine();
}

在沒有使用lock對象的時候,得出的結果如下:

可以看出。RunCountA!=RunCount ,RunCountC不等於RunCountA+RunCountB,這個就是對線程共用變量的問題。

下面加上lock鎖定,要鎖定,定義一個objct變量

再次執行代碼:

會得到我們期望的數值,介面如下:

2.使用mutex

 定義:private Mutex mutex = new Mutex();

 鎖定:mutex.WaitOne();從這裡開始的代碼變量是安全的。

  釋放:mutex.ReleaseMutex();

把lock 去掉,用這2個語句代替。也能達到上面的效果。

3.Monitor是一個靜態類,提供靜態方法。

首先:定義一個object 對象,必須是object對象,否則會出錯。

      if (Monitor.TryEnter(o))
{
Monitor.Enter(o);
if (!IsRunA)
{
RunCountB++;
RunCountC++;
IsRunA = !IsRunA;
}
Monitor.Exit(o);
}

Monitor.TryEnter(o) 是否能進入這塊區域

Monitor.Enter(o);鎖定區域

 Monitor.Exit(o);釋放區域

4.Interlocked 提供原子鎖定,也是提供靜態方法

其中usingResource為int ,必須定義為private  int usingResource = 0,因為第一次是從0開始。要和開始方法中的變量不同。

如果Interlocked.Exchange(ref usingResource, 1)是1則private  int usingResource = 0,否則private  int usingResource = 1

  if (0 == Interlocked.Exchange(ref usingResource, 1))進入鎖定區域

Interlocked.Exchange(ref usingResource, 0); 釋放鎖定區域

Interlocked.Increment(ref safeInstanceCount);原子遞增,相當於 safeInstanceCount++
Interlocked.Decrement(ref safeInstanceCount);原子遞減,相當於 safeInstanceCount--

5.WaitCallback使用,允許線程通過發訊號互相通訊

如:此計算的格式為:result = first term + second term + third term,其中每項都要求使用計算出的基數進行預計算和最終計算

此類,需要調用ThreadPool這個進行護理。

5.1 定義幾個處理方法

AutoResetEvent[] autoEvents
           autoEvents = new AutoResetEvent[]
        {
            new AutoResetEvent(false),
            new AutoResetEvent(false),
            new AutoResetEvent(false)
        };
初始狀態為運行狀態。
5.2 定義ManualResetEvent manualEvent;表示,是否能執行完這個線程,可以繼續執行下面的代碼
初始化為: manualEvent = new ManualResetEvent(false);
manualEvent.Reset();為線程結束,可以繼續下面的代碼
5.3使用ThreadPool線程池來執行線程
   ThreadPool.QueueUserWorkItem(
                new WaitCallback(CalculateBase));
            ThreadPool.QueueUserWorkItem(
                new WaitCallback(CalculateFirstTerm));
            ThreadPool.QueueUserWorkItem(
                new WaitCallback(CalculateSecondTerm));
            ThreadPool.QueueUserWorkItem(
                new WaitCallback(CalculateThirdTerm));
5.4對於每一個方法 autoEvents[0].Set();表示第二個方法結束,可以釋放信號。
manualEvent.Set();是第一個方法結束,進入manualEvent處理中。
最後在manualEvent.Reset();方法後,將得到的結果進行處理。
6.ThreadPool系統提供的線程池,託管線程池中的線程為後台線程,每個進程都有一個線程池。線程池的預設大小為每個可用處理器有 25 個線程。
使用 SetMaxThreads 方法可以更改線程池中的線程數。線程池中的線程,是自動執行的。
6.1ThreadPool.QueueUserWorkItem
將方法排入隊列以便執行。此方法在有線程池線程變得可用時執行。此方法,可以帶參數,可以傳遞給方法參數
 ThreadPool.QueueUserWorkItem(
                new WaitCallback(CalculateBase),"12");
7. LockCookie 單個編寫器/多個閱讀器語義的鎖
7.1 ReaderWriterLock rwl = new ReaderWriterLock();定義鎖
7.2 rwl.AcquireReaderLock(timeOut);讀取鎖開始
rwl.ReleaseReaderLock();釋放讀取鎖。
7.3 LockCookie lc = rwl.UpgradeToWriterLock(timeOut);定義寫鎖
rwl.DowngradeFromWriterLock(ref lc);釋放寫鎖。







 

               

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.