C#编程-在线程中使用同步-LMLPHP

C#编程-在线程中使用同步-LMLPHP

C#编程-在线程中使用同步-LMLPHP

在线程中使用同步

在线程应用程序中,线程需要相互共享数据。但是,应用程序应该确保一个线程不更改另一个线程使用的数据。考虑有两个线程的场景。一个线程从文件读取工资,另一个线程尝试更新工资。当两个线程同时工作时,数据就会受损。下图显示了两个线程同时访问一个文件的数据。
C#编程-在线程中使用同步-LMLPHP


同步线程

线程的同步确保如果两个或多个线程需要访问共享资源,那么那个资源一次仅被一个线程使用。您可以使用synchroized关键字同步代码。可以在任何给定的时间仅调用一个同步方法。

同步基于监视的概念。监视器时一个对象, 用于数据成员的锁以及类的方法。所有对象和类都与监视器关联,并且在指定时间只有一个线程能够拥有监视器。要进入一个对象的监视器,需要调用synchroized关键字修改的方法。

监视器控制同步方法访问一个对象或类的方法。当线程获取锁时,就是说它进入了监视器。监视器确保在任何给定的时间仅一个线程访问资源。

当线程在同步方法内的时候,所有试图在同一个实例上调用方法的其他线程必须等待。在同步方法执行的期间,对象时被锁定的以便没有其他的同步方法被调用。当方法完成其执行时会自动释放监视器。监视器也在同步方法执行Wait()方法的时候被释放。下图显示了线程同步的一个示例。
C#编程-在线程中使用同步-LMLPHP

在上图中,Thread1正在更新文件中Stella的工资时,在Salary.xls文件上有一个锁。Thread2要从Salary.xls文件读取Stella的工资,它正在等待Thread1释放文件上的锁。

当线程调用Wait()方法时,它暂时释放它拥有的锁。而且,线程停止运行,而且被加入到那个对象的等待线程列表中。

下图显示了线程间的同步。
C#编程-在线程中使用同步-LMLPHP

使用监视锁锁定代码
System.Monitor类能够以锁和信号的方式使代码块的访问序列化。例如,您有一个将内容写到文件的方法。此方法不应由两个或多个线程同时使用来讲内容写到文件。您可以使用Monitor类来锁定方法,以便在给定时间仅有一个线程能执行它。

考虑同步的示例。有两个进程,两个进程都将调用WriteData()方法。您可以使用以下方式锁定WriteData()方法:

  1. Monitor.Enter()方法。
  2. Lock语句。

使用监视锁及Monitor.Enter()方法
Monitor类的Enter()方法尝试获取对象上的监视锁。如果另一个线程已经有锁,会阻止方法直到锁被释放。然后调用Monitor.Exit()方法来释放此锁。

以下代码使用Monitor.Enter()方法锁定WriteData()方法:

	using System;
	using System.Threading;
	namespace ThreadExample
	{
   
		class FileAccess
		{
   
			public void WriteData(string Data)
			{
   
				Monitor.Enter(this);
				Console.WriteLine("FileAccess.WriteData - Started");
				Console.WriteLine("FileAccess.WriteData - Working");
				for ( int Cnt = 0; Cnt 
01-17 13:58