共用方式為


Interlocked 類別

定義

為多個線程共用的變數提供不可部分完成的作業。

public ref class Interlocked abstract sealed
public ref class Interlocked sealed
public static class Interlocked
public sealed class Interlocked
type Interlocked = class
Public Class Interlocked
Public NotInheritable Class Interlocked
繼承
Interlocked

範例

下列程式代碼範例顯示安全線程的資源鎖定機制。

using namespace System;
using namespace System::Threading;

const int numThreads = 10;
const int numThreadIterations = 5;
ref class MyInterlockedExchangeExampleClass
{
public:
   static void MyThreadProc()
   {
      for ( int i = 0; i < numThreadIterations; i++ )
      {
         UseResource();
         
         //Wait 1 second before next attempt.
         Thread::Sleep( 1000 );

      }
   }


private:
   //A simple method that denies reentrancy.
   static bool UseResource()
   {
      
      //0 indicates that the method is not in use.
      if ( 0 == Interlocked::Exchange( usingResource, 1 ) )
      {
         Console::WriteLine( " {0} acquired the lock", Thread::CurrentThread->Name );
         
         //Code to access a resource that is not thread safe would go here.
         //Simulate some work
         Thread::Sleep( 500 );
         Console::WriteLine( " {0} exiting lock", Thread::CurrentThread->Name );
         
         //Release the lock
         Interlocked::Exchange( usingResource, 0 );
         return true;
      }
      else
      {
         Console::WriteLine( " {0} was denied the lock", Thread::CurrentThread->Name );
         return false;
      }
   }


   //0 for false, 1 for true.
   static int usingResource;
};

int main()
{
   Thread^ myThread;
   Random^ rnd = gcnew Random;
   for ( int i = 0; i < numThreads; i++ )
   {
      myThread = gcnew Thread( gcnew ThreadStart( MyInterlockedExchangeExampleClass::MyThreadProc ) );
      myThread->Name = String::Format( "Thread {0}", i + 1 );
      
      //Wait a random amount of time before starting next thread.
      Thread::Sleep( rnd->Next( 0, 1000 ) );
      myThread->Start();

   }
}
using System;
using System.Threading;

namespace InterlockedExchange_Example
{
    class MyInterlockedExchangeExampleClass
    {
        //0 for false, 1 for true.
        private static int usingResource = 0;

        private const int numThreadIterations = 5;
        private const int numThreads = 10;

        static void Main()
        {
            Thread myThread;
            Random rnd = new Random();

            for(int i = 0; i < numThreads; i++)
            {
                myThread = new Thread(new ThreadStart(MyThreadProc));
                myThread.Name = String.Format("Thread{0}", i + 1);
            
                //Wait a random amount of time before starting next thread.
                Thread.Sleep(rnd.Next(0, 1000));
                myThread.Start();
            }
        }

        private static void MyThreadProc()
        {
            for(int i = 0; i < numThreadIterations; i++)
            {
                UseResource();
            
                //Wait 1 second before next attempt.
                Thread.Sleep(1000);
            }
        }

        //A simple method that denies reentrancy.
        static bool UseResource()
        {
            //0 indicates that the method is not in use.
            if(0 == Interlocked.Exchange(ref usingResource, 1))
            {
                Console.WriteLine("{0} acquired the lock", Thread.CurrentThread.Name);
            
                //Code to access a resource that is not thread safe would go here.
            
                //Simulate some work
                Thread.Sleep(500);

                Console.WriteLine("{0} exiting lock", Thread.CurrentThread.Name);
            
                //Release the lock
                Interlocked.Exchange(ref usingResource, 0);
                return true;
            }
            else
            {
                Console.WriteLine("   {0} was denied the lock", Thread.CurrentThread.Name);
                return false;
            }
        }
    }
}
Imports System.Threading

Namespace InterlockedExchange_Example
    Class MyInterlockedExchangeExampleClass
        '0 for false, 1 for true.
        Private Shared usingResource As Integer = 0

        Private Const numThreadIterations As Integer = 5
        Private Const numThreads As Integer = 10

        <MTAThread> _
        Shared Sub Main()
            Dim myThread As Thread
            Dim rnd As New Random()

            Dim i As Integer
            For i = 0 To numThreads - 1
                myThread = New Thread(AddressOf MyThreadProc)
                myThread.Name = String.Format("Thread{0}", i + 1)

                'Wait a random amount of time before starting next thread.
                Thread.Sleep(rnd.Next(0, 1000))
                myThread.Start()
            Next i
        End Sub

        Private Shared Sub MyThreadProc()
            Dim i As Integer
            For i = 0 To numThreadIterations - 1
                UseResource()

                'Wait 1 second before next attempt.
                Thread.Sleep(1000)
            Next i
        End Sub 

        'A simple method that denies reentrancy.
        Shared Function UseResource() As Boolean
            '0 indicates that the method is not in use.
            If 0 = Interlocked.Exchange(usingResource, 1) Then
                Console.WriteLine("{0} acquired the lock", Thread.CurrentThread.Name)

                'Code to access a resource that is not thread safe would go here.
                'Simulate some work
                Thread.Sleep(500)

                Console.WriteLine("{0} exiting lock", Thread.CurrentThread.Name)

                'Release the lock
                Interlocked.Exchange(usingResource, 0)
                Return True
            Else
                Console.WriteLine("   {0} was denied the lock", Thread.CurrentThread.Name)
                Return False
            End If
        End Function 
    End Class 
End Namespace

備註

這個類別的方法有助於防止排程器在線程更新可由其他線程存取的變數時,或當兩個線程同時在不同的處理器上執行時,可能會發生的錯誤。 這個類別的成員不會擲回例外狀況。

IncrementDecrement 方法會遞增或遞減變數,並將產生的值儲存在單一作業中。 在大部分計算機上,遞增變數不是不可部分完成的作業,需要下列步驟:

  1. 將實例變數的值載入緩存器。

  2. 遞增或遞減值。

  3. 將值儲存在實例變數中。

如果您未使用 IncrementDecrement,在執行前兩個步驟之後,就可以先占線程。 接著,另一個線程可以執行這三個步驟。 當第一個線程繼續執行時,它會覆寫實例變數中的值,並遺失第二個線程所執行的遞增或遞減效果。

Add 方法會不可部分完成地將整數值加入至整數變數,並傳回變數的新值。

Exchange 方法會以不可部分完成的方式交換指定變數的值。 CompareExchange 方法結合兩個作業:比較兩個值,並根據比較的結果,將第三個值儲存在其中一個變數中。 比較和交換作業會以不可部分完成的作業的形式執行。

請確定共用變數的任何寫入或讀取許可權都是不可部分完成的。 否則,數據可能會損毀,或載入的值可能不正確。

方法

Add(Int32, Int32)

加入兩個 32 位整數,並以總和取代第一個整數,做為不可部分完成的作業。

Add(Int64, Int64)

加入兩個 64 位整數,並以總和取代第一個整數,做為不可部分完成的作業。

Add(UInt32, UInt32)

新增兩個 32 位無符號整數,並以總和取代第一個整數,做為不可部分完成的作業。

Add(UInt64, UInt64)

新增兩個 64 位無符號整數,並以總和取代第一個整數,做為不可部分完成的作業。

And(Int32, Int32)

位 “ands” 兩個 32 位帶正負號的整數,並以結果取代第一個整數,做為不可部分完成的作業。

And(Int64, Int64)

位 “ands” 兩個 64 位帶正負號的整數,並以結果取代第一個整數,做為不可部分完成的作業。

And(UInt32, UInt32)

位 “ands” 兩個 32 位無符號整數,並以結果取代第一個整數,做為不可部分完成的作業。

And(UInt64, UInt64)

位 “ands” 兩個 64 位無符號整數,並以結果取代第一個整數,做為不可部分完成的作業。

CompareExchange(Byte, Byte, Byte)

比較兩個 8 位無符號整數是否相等,如果相等,則會將第一個值取代為不可部分完成的作業。

CompareExchange(Double, Double, Double)

比較兩個雙精確度浮點數是否相等,如果相等,則會將第一個值取代為不可部分完成的作業。

CompareExchange(Int16, Int16, Int16)

比較兩個 16 位無符號整數是否相等,如果相等,則會將第一個值取代為不可部分完成的作業。

CompareExchange(Int32, Int32, Int32)

比較兩個 32 位帶正負號的整數是否相等,如果相等,則會將第一個值取代為不可部分完成的作業。

CompareExchange(Int64, Int64, Int64)

比較兩個 64 位帶正負號的整數是否相等,如果相等,則會將第一個值取代為不可部分完成的作業。

CompareExchange(IntPtr, IntPtr, IntPtr)

比較兩個平臺特定的句柄或指標是否相等,如果相等,則會將第一個句柄取代為不可部分完成的作業。

CompareExchange(Object, Object, Object)

比較兩個對象的參考相等,如果相等,則會將第一個物件取代為不可部分完成的作業。

CompareExchange(SByte, SByte, SByte)

比較兩個 8 位帶正負號的整數是否相等,如果相等,則會將第一個值取代為不可部分完成的作業。

CompareExchange(Single, Single, Single)

比較兩個單精度浮點數是否相等,如果相等,則會將第一個值取代為不可部分完成的作業。

CompareExchange(UInt16, UInt16, UInt16)

比較兩個 16 位帶正負號的整數是否相等,如果相等,則會將第一個值取代為不可部分完成的作業。

CompareExchange(UInt32, UInt32, UInt32)

比較兩個 32 位無符號整數是否相等,如果相等,則會將第一個值取代為不可部分完成的作業。

CompareExchange(UInt64, UInt64, UInt64)

比較兩個 64 位無符號整數是否相等,如果相等,則會將第一個值取代為不可部分完成的作業。

CompareExchange(UIntPtr, UIntPtr, UIntPtr)

比較兩個平臺特定的句柄或指標是否相等,如果相等,則會將第一個句柄取代為不可部分完成的作業。

CompareExchange<T>(T, T, T)

比較指定之參考型別的兩個實例 T 的參考相等,如果相等,則會將第一個實例取代為不可部分完成的作業。

Decrement(Int32)

遞減指定的變數,並將結果儲存為不可部分完成的作業。

Decrement(Int64)

遞減指定的變數,並將結果儲存為不可部分完成的作業。

Decrement(UInt32)

遞減指定的變數,並將結果儲存為不可部分完成的作業。

Decrement(UInt64)

遞減指定的變數,並將結果儲存為不可部分完成的作業。

Exchange(Byte, Byte)

將 8 位無符號整數設定為指定的值,並以不可部分完成的作業傳回原始值。

Exchange(Double, Double)

將雙精確度浮點數設定為指定的值,並以不可部分完成的作業傳回原始值。

Exchange(Int16, Int16)

將16位無符號整數設定為指定的值,並以不可部分完成的作業傳回原始值。

Exchange(Int32, Int32)

將 32 位帶正負號的整數設定為指定的值,並以不可部分完成的作業傳回原始值。

Exchange(Int64, Int64)

將 64 位帶正負號的整數設定為指定的值,並以不可部分完成的作業傳回原始值。

Exchange(IntPtr, IntPtr)

將平臺特定的句柄或指標設定為指定的值,並以不可部分完成的作業傳回原始值。

Exchange(Object, Object)

將物件設定為指定的值,並將原始對象的參考當做不可部分完成的作業傳回。

Exchange(SByte, SByte)

將8位帶正負號的整數設定為指定的值,並以不可部分完成的作業傳回原始值。

Exchange(Single, Single)

將單精度浮點數設定為指定的值,並以不可部分完成的作業傳回原始值。

Exchange(UInt16, UInt16)

將16位帶正負號的整數設定為指定的值,並以不可部分完成的作業傳回原始值。

Exchange(UInt32, UInt32)

將 32 位無符號整數設定為指定的值,並以不可部分完成的作業傳回原始值。

Exchange(UInt64, UInt64)

將 64 位無符號整數設定為指定的值,並以不可部分完成的作業傳回原始值。

Exchange(UIntPtr, UIntPtr)

將平臺特定的句柄或指標設定為指定的值,並以不可部分完成的作業傳回原始值。

Exchange<T>(T, T)

將指定型別的變數 T 設定為指定的值,並以不可部分完成的作業傳回原始值。

Increment(Int32)

遞增指定的變數,並將結果儲存為不可部分完成的作業。

Increment(Int64)

遞增指定的變數,並將結果儲存為不可部分完成的作業。

Increment(UInt32)

遞增指定的變數,並將結果儲存為不可部分完成的作業。

Increment(UInt64)

遞增指定的變數,並將結果儲存為不可部分完成的作業。

MemoryBarrier()

同步處理記憶體存取,如下所示:執行目前線程的處理器無法重新排序指令,如此一來,在呼叫 MemoryBarrier() 之後,在呼叫 之後執行的記憶體存取之後,MemoryBarrier()

MemoryBarrierProcessWide()

提供全進程記憶體屏障,確保從任何 CPU 讀取和寫入無法跨屏障移動。

Or(Int32, Int32)

位 「ors」 兩個 32 位帶正負號的整數,並以結果取代第一個整數,做為不可部分完成的作業。

Or(Int64, Int64)

位 「ors」 兩個 64 位帶正負號的整數,並以結果取代第一個整數,做為不可部分完成的作業。

Or(UInt32, UInt32)

位 「ors」 兩個 32 位無符號整數,並以結果取代第一個整數,做為不可部分完成的作業。

Or(UInt64, UInt64)

位 「ors」 兩個 64 位無符號整數,並以結果取代第一個整數,做為不可部分完成的作業。

Read(Int64)

傳回 64 位值,當做不可部分完成的作業載入。

Read(UInt64)

傳回以不可部分完成作業方式載入的64位無符號值。

SpeculationBarrier()

定義記憶體柵欄,封鎖超過這個點的推測性執行,直到擱置的讀取和寫入完成為止。

適用於

執行緒安全性

此類型是安全線程。

另請參閱