Export (0) Print
Expand All
1 out of 12 rated this helpful - Rate this topic

Interlocked Class

Provides atomic operations for variables that are shared by multiple threads.

For a list of all members of this type, see Interlocked Members.

System.Object
   System.Threading.Interlocked

[Visual Basic]
NotInheritable Public Class Interlocked
[C#]
public sealed class Interlocked
[C++]
public __gc __sealed class Interlocked
[JScript]
public class Interlocked

Thread Safety

This type is safe for multithreaded operations.

Remarks

The methods of this class help protect against errors that can occur when the scheduler switches contexts while a thread is updating a variable that can be accessed by other threads, or when two threads are executing concurrently on separate processors. The members of this class do not throw exceptions.

The Increment and Decrement methods increment or decrement a variable and store the resulting value in a single operation. On most computers, incrementing a variable is not an atomic operation, requiring the following steps:

  1. Load a value from an instance variable into a register.
  2. Increment or decrement the value.
  3. Store the value in the instance variable.

If you do not use Increment and Decrement, a thread can be preempted after executing the first two steps. Another thread can then execute all three steps. When the first thread resumes execution, it overwrites the value in the instance variable, and the effect of the increment or decrement performed by the second thread is lost.

The Exchange method atomically exchanges the values of the specified variables. The CompareExchange method combines two operations: comparing two values and storing a third value in one of the variables, based on the outcome of the comparison. The compare and exchange operations are performed as an atomic operation.

Example

[Visual Basic, C#, C++] The following code example shows a thread-safe resource locking mechanism.

[Visual Basic] 
Imports System
Imports System.Threading

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

        Private Shared currentMso As [Object]
        Private Shared globalMso As New [Object]()
        Private Const numThreadIterations As Integer = 5
        Private Const numThreads As Integer = 10

        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 'Main

        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 'MyThreadProc

        '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 'UseResource
    End Class 'MyInterlockedExchangeExampleClass 
End Namespace 'InterlockedExchange_Example

[C#] 
using System;
using System.Threading;

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

        private static Object currentMso;
        private static Object globalMso = new Object();
        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;
            }
        }

    }
}  

[C++] 
#using <mscorlib.dll>

using namespace System;
using namespace System::Threading;

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

__gc 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(S" {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(S" {0} exiting lock", Thread::CurrentThread->Name);

            //Release the lock
            Interlocked::Exchange( &usingResource, 0);
            return true;
        }
        else 
        {
            Console::WriteLine(S" {0} was denied the lock", Thread::CurrentThread->Name);
            return false;
        }
    }
private:
    //0 for false, 1 for true.
    static int usingResource;
    static Object* globalMso = new Object();
};

void main() 
{
    Thread* myThread;
    Random* rnd = new Random();

    for (int i = 0; i < numThreads; i++) 
    {
        myThread = new Thread(new ThreadStart(0, MyInterlockedExchangeExampleClass::MyThreadProc));
        myThread->Name = String::Format(S"Thread {0}", __box(i + 1));

        //Wait a random amount of time before starting next thread.
        Thread::Sleep(rnd->Next(0, 1000));
        myThread->Start();
    }
}

[JScript] No example is available for JScript. To view a Visual Basic, C#, or C++ example, click the Language Filter button Language Filter in the upper-left corner of the page.

Requirements

Namespace: System.Threading

Platforms: Windows 98, Windows NT 4.0, Windows Millennium Edition, Windows 2000, Windows XP Home Edition, Windows XP Professional, Windows Server 2003 family, .NET Compact Framework

Assembly: Mscorlib (in Mscorlib.dll)

See Also

Interlocked Members | System.Threading Namespace | Threading | Interlocked

Show:
© 2014 Microsoft. All rights reserved.