C#教程

关注公众号 jb51net

关闭
首页 > 软件编程 > C#教程 > C# 多线程同步

C#多线程同步不同实现方式小结

作者:語衣

本文主要介绍了C#多线程同步不同实现方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

AutoResetEvent

class MainClass
{
	// the array of consumer threads
	private static List<Thread> consumers = new List<Thread> ();

	// the task queue
	private static Queue<Action> tasks = new Queue<Action>();

	// the synchronisation object for locking the task queue
	private static readonly object queueLock = new object();

	// this wait handle notifies consumers of a new task
	private static EventWaitHandle newTaskAvailable = new AutoResetEvent (false);

	// the synchronisation object for locking the console color
	private static readonly object consoleLock = new object();


	// enqueue a new task
	private static void EnqueueTask (Action task)
	{
		lock (queueLock)
		{
			tasks.Enqueue (task);
		}
		newTaskAvailable.Set();
	}


	// thread work method for consumers
	private static void DoWork(ConsoleColor color)
	{
		while (true)
		{
			// get a new task
			Action task = null;
			lock (queueLock) {
				if (tasks.Count > 0)
				{
					task = tasks.Dequeue ();
				}
			}
			if (task != null)
			{
				// set console to this task's color
				lock (consoleLock)
				{
					Console.ForegroundColor = color;
				}

				// execute task
				task ();
			}
			else
				// queue is empty - wait for a new task
				newTaskAvailable.WaitOne();
		}
	}

	public static void Main (string[] args)
	{
		// set up 3 consumers
		consumers.Add(new Thread ( () => { DoWork(ConsoleColor.Red); }));
		consumers.Add(new Thread ( () => { DoWork(ConsoleColor.Green); }));
		consumers.Add(new Thread ( () => { DoWork(ConsoleColor.Blue); }));

		// start all consumers
		consumers.ForEach ( (t) => { t.Start (); });

		while (true)
		{
			// add a new task
			Random r = new Random();
			EnqueueTask ( () => {

				// the task is to write a random number to the console
				int number = r.Next (10);
				Console.Write (number);

			});

			// random sleep to simulate workload
			Thread.Sleep (r.Next (1000)); 
		}
	}
}

这段代码实现了一个简单的生产者-消费者模型,其中有一个生产者(在Main方法中模拟)和多个消费者(在这个例子中是三个线程,每个线程代表一个消费者)。这个模型通过共享的任务队列来同步生产者和消费者之间的工作。

代码功能概述:

代码执行流程:

ManualResetEvent

class MainClass
{
	// the array of consumer threads
	private static List<Thread> consumers = new List<Thread> ();

	// the task queue
	private static Queue<Action> tasks = new Queue<Action>();

	// the synchronisation object for locking the task queue
	private static readonly object queueLock = new object();

	// this wait handle notifies consumers of a new task
	private static EventWaitHandle newTaskAvailable = new AutoResetEvent (false);

	// this wait handle pauses consumers
	private static EventWaitHandle pauseConsumers = new ManualResetEvent (true);

	// the synchronisation object for locking the console color
	private static readonly object consoleLock = new object();


	// enqueue a new task
	private static void EnqueueTask (Action task)
	{
		lock (queueLock)
		{
			tasks.Enqueue (task);
		}
		newTaskAvailable.Set();
	}


	// thread work method for consumers
	private static void DoWork(ConsoleColor color)
	{
		while (true)
		{
			// check if producer asked us to pause
			pauseConsumers.WaitOne ();

			// get a new task
			Action task = null;
			lock (queueLock) {
				if (tasks.Count > 0)
				{
					task = tasks.Dequeue ();
				}
			}
			if (task != null)
			{
				// set console to this task's color
				lock (consoleLock)
				{
					Console.ForegroundColor = color;
				}

				// execute task
				task ();
			}
			else
				// queue is empty - wait for a new task
				newTaskAvailable.WaitOne();
		}
	}

	public static void Main (string[] args)
	{
		// set up 3 consumers
		consumers.Add(new Thread ( () => { DoWork(ConsoleColor.Red); }));
		consumers.Add(new Thread ( () => { DoWork(ConsoleColor.Green); }));
		consumers.Add(new Thread ( () => { DoWork(ConsoleColor.Blue); }));

		// start all consumers
		consumers.ForEach ( (t) => { t.Start (); });

		bool consumersPaused = false;

		while (true)
		{
			// add a new task
			Random r = new Random();
			EnqueueTask ( () => {

				// the task is to write a random number to the console
				int number = r.Next (10);
				Console.Write (number);

			});

			// random sleep to simulate workload
			Thread.Sleep (r.Next (1000)); 

			// pressing any key pauses/unpauses the consumers
			if (Console.KeyAvailable)
			{
				Console.Read ();
				if (consumersPaused)
				{
					pauseConsumers.Set ();
					Console.WriteLine ("Consumers resumed");
				}
				else
				{
					pauseConsumers.Reset ();
					Console.WriteLine ("Consumers paused");
				}

				consumersPaused = !consumersPaused;
			}
		}
	}
}

这段代码实现了一个带有暂停/恢复功能的生产者-消费者模型,其中包含一个生产者(在Main方法中模拟)和三个消费者线程。这个模型通过共享的任务队列来同步生产者和消费者之间的工作,并且允许用户通过按键操作来暂停或恢复消费者的执行。

代码功能概述:

代码执行流程:

CountdownEvent

class MainClass
{
	// the array of consumer threads
	private static List<Thread> consumers = new List<Thread> ();

	// the task queue
	private static Queue<Action> tasks = new Queue<Action>();

	// the synchronisation object for locking the task queue
	private static readonly object queueLock = new object();

	// this wait handle notifies consumers of a new task
	private static EventWaitHandle newTaskAvailable = new AutoResetEvent (false);

	// the wait handle to quit consumers
	private static CountdownEvent quitConsumers = new CountdownEvent (3);

	// the flag to request that consumers quit
	private static bool quitRequested = false;

	// the synchronisation object for quitting consumers
	private static readonly object quitLock = new object ();

	// the synchronisation object for locking the console color
	private static readonly object consoleLock = new object();


	// enqueue a new task
	private static void EnqueueTask (Action task)
	{
		lock (queueLock)
		{
			tasks.Enqueue (task);
		}
		newTaskAvailable.Set();
	}


	// thread work method for consumers
	private static void DoWork(ConsoleColor color)
	{
		while (true)
		{
			// check if someone asked us to quit
			lock (quitLock)
			{
				if (quitRequested)
				{
					Console.WriteLine ("Consumer {0} is quitting", color);
					quitConsumers.Signal ();
					break;
				}
			}

			// get a new task
			Action task = null;
			lock (queueLock) {
				if (tasks.Count > 0)
				{
					task = tasks.Dequeue ();
				}
			}
			if (task != null)
			{
				// set console to this task's color
				lock (consoleLock)
				{
					Console.ForegroundColor = color;
				}

				// execute task
				task ();
			}
			else
				// queue is empty - wait for a new task
				newTaskAvailable.WaitOne(1000);
		}
	}

	public static void Main (string[] args)
	{
		// set up 3 consumers
		consumers.Add(new Thread ( () => { DoWork(ConsoleColor.Red); }));
		consumers.Add(new Thread ( () => { DoWork(ConsoleColor.Green); }));
		consumers.Add(new Thread ( () => { DoWork(ConsoleColor.Blue); }));

		// start all consumers
		consumers.ForEach ( (t) => { t.Start (); });

		int iterations = 0;

		while (true)
		{
			// add a new task
			Random r = new Random();
			EnqueueTask ( () => {

				// the task is to write a random number to the console
				int number = r.Next (10);
				Console.Write (number);

			});

			// random sleep to simulate workload
			Thread.Sleep (r.Next (1000)); 

			// quit after 10 iterations
			if (iterations++ >= 10)
			{
				// request consumer quit
				lock (quitLock)
				{
					quitRequested = true;
				}

				// wait until all consumers have signalled
				quitConsumers.Wait ();

				Console.WriteLine ("All consumers have quit");
				break;
			}
		}
	}
}

这个代码实现了一个带有优雅退出机制的生产者-消费者模型。它创建了三个消费者线程,这些线程从共享的任务队列中取出并执行任务。与之前的代码相比,这个代码添加了以下主要功能和改进:

Barrier

class MainClass
{
    // wait handles to rendezvous threads  
    public static Barrier barrier = new Barrier(3, b => Console.WriteLine("All threads have reached the barrier."));

    // thread work method  
    public static void DoWork()
    {
        for (int i = 0; i < 5; i++)
        {
            Console.Write(Thread.CurrentThread.ManagedThreadId + ": " + i + " ");

            // rendezvous with other threads  
            barrier.SignalAndWait();
        }
    }

    public static void Main(string[] args)
    {
        // start three threads  
        new Thread(DoWork).Start();
        new Thread(DoWork).Start();
        new Thread(DoWork).Start();

        // Keep the main thread alive to prevent the program from exiting before the threads finish  
        Console.WriteLine("Press Enter to exit...");
        Console.ReadLine();
    }
}

代码功能概述:

运行结果

到此这篇关于C#多线程同步不同实现方式小结的文章就介绍到这了,更多相关C# 多线程同步内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家! 

您可能感兴趣的文章:
阅读全文