Go homepage(回首页)
Upload pictures (上传图片)
Write articles (发文字帖)

The author:(作者)qq
published in(发表于) 2014/7/11 9:28:04
C#教程:线程同步

C#教程:线程同步

线程同步

在应用程序中使用多个线程的优点是每个线程都可以异步执行。对于 Windows 应用程序,耗时的任务可以在后台执行,而使应用程序窗口和控件保持响应。对于服务器应用程序,多线程处理提供了用不同线程处理每个传入请求的能力。否则,在完全满足前一个请求之前,将无法处理每个新请求。

线程的异步特性意味着必须协调对资源(如文件句柄、网络连接和内存)的访问。否则,两个或更多的线程可能在同一时间访问相同的资源,而每个线程都不知道其他线程的操作,结果将产生不可预知的数据损坏。

线程同步是指并发线程高效、有序的访问共享资源所采用的技术。其目的是要确保线程安全。如果类或其成员能被多个线程访问,而且不会破坏其状态,则称之为线程安全。

线程同步的本质是在指定的时间内,只允许一个线程有资源的所有权,只有当资源所有者主动放弃了代码或资源的所有权时,其他线程才能使用这些资源。下面讲解实现这个策略的不同同步技术。

1.监视器

监视器可防止多个线程同时执行代码块。Monitor类就是用来实现监视器技术的。Monitor类允许单个线程为对象加锁。Monitor 的方法用于控制整个对象或对象中部分代码的访问。其中最常用的方法是Enter和Exit,Enter为调用线程分配所有权,并禁止其他线程在该线程拥有所有权期间获得锁的所有权。Exit释放锁的所有权。

Monitor的静态方法Enter的参数为对象,并赋予当前线程对该对象地独占访问权限。如果另一个线程拥有该对象的访问权限,则阻塞请求线程直到该对象被释放为止。执行对应的Exit方法可以释放对象。

示例

使用监视器实现线程安全

下面的代码使用监视器锁定对象TestClass。

public void MonitorTest()

{

Monitor.Enter(TestClass);

TestClass.Update();

Monitor.Exit(TestClass);

}

完整程序代码如下:

★ ★★★★Program.cs主程序文件完整程序代码★★★★★

using System;

using System.Collections.Generic;

using System.Text;

namespace _8_04

{

class Program

{

static void Main(string[] args)

{

}

public void MonitorTest()

{

Monitor.Enter(TestClass);

TestClass.Update();

Monitor.Exit(TestClass);

}

}

}

如果有两个线程同时调用这个方法,则Monitor.Enter()方法将会锁定对象,直到操作完毕。这种方法可以实现两个调用MonitorTest()方法的线程的安全,但却不能阻止其他线程中直接调用TestClass.Update()方法。更好的方法是直接在Update()方法中封装锁。

示例

在方法中使用监视器

下面的代码实现了在Update方法中使用监视器锁定对象。

public void Update()

{

Monitor.Enter(this);

try

{

//将要执行的代码

}

finally

{

Monitor.Exit();

}

}

完整程序代码如下:

★ ★★★★Program.cs主程序文件完整程序代码★★★★★

using System;

using System.Collections.Generic;

using System.Text;

namespace _8_05

{

class Program

{

static void Main(string[] args)

{

}

public void Update()

{

Monitor.Enter(this);

try

{

//将要执行的代码

}

finally

{

Monitor.Exit();

}

}

}

}

2.lock关键字

Update()方法封装锁也可以用lock关键字实现,它等效于try/finally语句块。例如:

lock(this)

{

//将要执行的代码

}

提供给lock关键字的参数必须为基于引用类型的对象,该对象用来定义锁的范围。在上例中,锁的范围限定为此函数,因为函数外不存在任何对该对象的引用。严格地说,提供给 lock 的对象只是用来惟一地标识由多个线程共享的资源,所以它可以是任意类实例。然而,实际上,此对象通常表示需要进行线程同步的资源。例如,如果一个容器对象将被多个线程使用,则可以将该容器传递给lock,而lock后面的同步代码块将访问该容器。只要其他线程在访问该容器前先锁定该容器,则对该对象的访问将是安全同步的。


If you have any requirements, please contact webmaster。(如果有什么要求,请联系站长)





QQ:154298438
QQ:417480759