Tải bản đầy đủ - 0 (trang)
4-11. Synchronize Access to a Shared Data Value

4-11. Synchronize Access to a Shared Data Value

Tải bản đầy đủ - 0trang

CHAPTER 4 ■ THREADS, PROCESSES, AND SYNCHRONIZATION



Interlocked class, you will need to implement your own synchronization using the other approaches

described in this chapter.



■ Caution The atomicity of 64-bit interlocked operations on 32-bit platforms are guaranteed only when the data

value is accessed through the Interlocked class—i.e., that the variable is not accessed directly.



Table 4-2. Interlocked Methods for Synchronizing Data Access



Method



Description



Add



Adds two int or long values and sets the value of the first argument to the sum of the

two values.



CompareExchange



Compares two values; if they are the same, sets the first argument to a specified

value. This method has overloads to support the comparison and exchange of int,

long, float, double, object, and System.IntPtr.



Decrement



Decrements an int or long value.



Exchange



Sets the value of a variable to a specified value. This method has overloads to support

the exchange of int, long, float, double, object, and System.IntPtr.



Increment



Increments an int or a long value.



The Code

The following simple example demonstrates how to use the methods of the Interlocked class. The

example does not demonstrate Interlocked in the context of a multithreaded program and is provided

only to clarify the syntax and effect of the various methods.

using System;

using System.Threading;

namespace Apress.VisualCSharpRecipes.Chapter04

{

class Recipe04_11

{

public static void Main()

{

int firstInt = 2500;

int secondInt = 8000;



188



www.it-ebooks.info



CHAPTER 4 ■ THREADS, PROCESSES, AND SYNCHRONIZATION



Console.WriteLine("firstInt initial value = {0}", firstInt);

Console.WriteLine("secondInt initial value = {0}", secondInt);

// Decrement firstInt in a thread-safe manner.

// The thread-safe equivalent of firstInt = firstInt - 1.

Interlocked.Decrement(ref firstInt);

Console.WriteLine(Environment.NewLine);

Console.WriteLine("firstInt after decrement = {0}", firstInt);

// Increment secondInt in a thread-safe manner.

// The thread-safe equivalent of secondInt = secondInt + 1.

Interlocked.Increment(ref secondInt);

Console.WriteLine("secondInt after increment = {0}", secondInt);

// Add the firstInt and secondInt values, and store the result in

// firstInt.

// The thread-safe equivalent of firstInt = firstInt + secondInt.

Interlocked.Add(ref firstInt, secondInt);

Console.WriteLine(Environment.NewLine);

Console.WriteLine("firstInt after Add = {0}", firstInt);

Console.WriteLine("secondInt after Add = {0}", secondInt);

// Exchange the value of firstInt with secondInt.

// The thread-safe equivalenet of secondInt = firstInt.

Interlocked.Exchange(ref secondInt, firstInt);

Console.WriteLine(Environment.NewLine);

Console.WriteLine("firstInt after Exchange = {0}", firstInt);

Console.WriteLine("secondInt after Exchange = {0}", secondInt);

// Compare firstInt with secondInt, and if they are equal, set

// firstInt to 5000.

// The thread-safe equivalenet of:

//

if (firstInt == secondInt) firstInt = 5000.

Interlocked.CompareExchange(ref firstInt, 5000, secondInt);

Console.WriteLine(Environment.NewLine);

Console.WriteLine("firstInt after CompareExchange = {0}", firstInt);

Console.WriteLine("secondInt after CompareExchange = {0}", secondInt);

// Wait to continue.

Console.WriteLine(Environment.NewLine);

Console.WriteLine("Main method complete. Press Enter.");

Console.ReadLine();

}

}

}



189



www.it-ebooks.info



CHAPTER 4 ■ THREADS, PROCESSES, AND SYNCHRONIZATION



4-12. Know When a Thread Finishes

Problem

You need to know when a thread has finished.



Solution

Use the IsAlive property or the Join method of the Thread class.



How It Works

The easiest way to test whether a thread has finished executing is to test the Thread.IsAlive property.

The IsAlive property returns true if the thread has been started but has not terminated or been aborted.

The IsAlive property provides a simple test to see whether a thread has finished executing, but

commonly you will need one thread to wait for another thread to complete its processing. Instead of

testing IsAlive in a loop, which is inefficient, you can use the Thread.Join method.

Join causes the calling thread to block until the referenced thread terminates, at which point the

calling thread will continue. You can optionally specify an int or a TimeSpan value that specifies the time,

after which the Join operation will time out and execution of the calling thread will resume. If you

specify a timeout value, Join returns true if the thread terminated and false if Join timed out.



The Code

The following example executes a second thread and then calls Join (with a timeout of 2 seconds) to wait

for the second thread to terminate. Because the second thread takes about 5 seconds to execute, the Join

method will always time out, and the example will display a message to the console. The example then

calls Join again without a timeout and blocks until the second thread terminates.

using System;

using System.Threading;

namespace Apress.VisualCSharpRecipes.Chapter04

{

class Recipe04_12

{

private static void DisplayMessage()

{

// Display a message to the console five times.

for (int count = 0; count < 5; count++)

{

Console.WriteLine("{0} : DisplayMessage thread",

DateTime.Now.ToString("HH:mm:ss.ffff"));



190



www.it-ebooks.info



CHAPTER 4 ■ THREADS, PROCESSES, AND SYNCHRONIZATION



// Sleep for 1 second.

Thread.Sleep(1000);

}

}

public static void Main()

{

// Create a new Thread to run the DisplayMessage method.

Thread thread = new Thread(DisplayMessage);

Console.WriteLine("{0} : Starting DisplayMessage thread.",

DateTime.Now.ToString("HH:mm:ss.ffff"));

// Start the DisplayMessage thread.

thread.Start();

// Block until the DisplayMessage thread finishes, or time out after

// 2 seconds.

if (!thread.Join(2000))

{

Console.WriteLine("{0} : Join timed out !!",

DateTime.Now.ToString("HH:mm:ss.ffff"));

}

// Print out the thread status.

Console.WriteLine("Thread alive: {0}", thread.IsAlive);

// Block again until the DisplayMessage thread finishes with no timeout.

thread.Join();

// Print out the thread status.

Console.WriteLine("Thread alive: {0}", thread.IsAlive);

// Wait to continue.

Console.WriteLine("Main method complete. Press Enter.");

Console.ReadLine();

}

}

}



4-13. Terminate the Execution of a Thread

Problem

You need to terminate an executing thread without waiting for it to finish on its own.



191



www.it-ebooks.info



Tài liệu bạn tìm kiếm đã sẵn sàng tải về

4-11. Synchronize Access to a Shared Data Value

Tải bản đầy đủ ngay(0 tr)

×