HTML5技术

.NET基础拾遗(5)多线程开发基础 - Edison Chou(8)

字号+ 作者:H5之家 来源:博客园 2015-10-01 12:20 我要评论( )

(); public void Work(){ lock (locker){ // 做一些需要线程同步的工作 }} 事实上,lock关键字时一个方便程序员使用的语法糖,它等效于安全地使用System.Threading.Monitor类型,它直接等效于下面的代码: (); publ

(); public void Work() { lock (locker) { // 做一些需要线程同步的工作 } }

  事实上,lock关键字时一个方便程序员使用的语法糖,它等效于安全地使用System.Threading.Monitor类型,它直接等效于下面的代码:

(); public void Work() { temp = locker; Monitor.Enter(temp); try { // 做一些需要线程同步的工作 } finally { Monitor.Exit(temp); } }

  (2)System.Threading.Monitor类型的作用和使用

  Monitor类型的Enter和Exit方法用来实现进入和退出对象的同步,当Enter方法被调用时,对象的同步索引将被检查,并且.NET将负责一系列的后续工作来保证对象访问时的线程同步,而Exit方法的调用则保证了当前线程释放该对象的同步块。

  下面的代码示例演示了如何使用lock关键字来实现线程同步:

class Program { static void Main(string[] args) { // 多线程测试静态方法的同步 Console.WriteLine(); for (int i = 0; i < 5; i++) { Thread thread = new Thread(Lock.StaticIncrement); thread.Start(); } // 这里等待线程执行结束 Thread.Sleep(5 * 1000); Console.WriteLine(); // 多线程测试实例方法的同步 Console.WriteLine(); Lock l = new Lock(); for (int i = 0; i < 6; i++) { Thread thread = new Thread(l.InstanceIncrement); thread.Start(); } Console.ReadKey(); } } public class Lock { staticLocker = new object(); instanceLocker = new object(); staticNumber = 0; private int instanceNumber = 0; StaticIncrement(object state) { lock (staticLocker) { Console.WriteLine(, Thread.CurrentThread.ManagedThreadId.ToString()); Console.WriteLine(, staticNumber.ToString()); // 这里可以制造线程并行执行的机会,来检查同步的功能 Thread.Sleep(200); staticNumber++; Console.WriteLine(, staticNumber.ToString()); } } InstanceIncrement(object state) { lock (instanceLocker) { Console.WriteLine(,Thread.CurrentThread.ManagedThreadId.ToString()); Console.WriteLine(, instanceNumber.ToString()); // 这里可以制造线程并行执行的机会,来检查同步的功能 Thread.Sleep(200); instanceNumber++; Console.WriteLine(, instanceNumber.ToString()); } } }

View Code

  下图是该实例的执行结果:

  

PS:线程同步本身违反了多线程并行运行的原则,所以我们在使用线程同步时应该尽量做到将lock加在最小的程序块上。对于静态方法的同步,一般采用静态私有的引用对象成员,而对于实例方法的同步,一般采用私有的引用对象成员。

3.3 可否使用值类型对象来实现线程同步吗?

  前面已经说到,在.NET中每个堆内的对象都会有一个同步索引字段,用以指向同步块的位置。但是,对于值类型来说,它们的对象是分配在堆栈上的,也就是说值类型是没有同步索引这一字段的,所以直接使用值类型对象无法实现线程同步。

  如果在程序中对于lock关键字使用了值类型对象,会直接导致一个编译错误:

3.4 可否使用引用类型对象自身进行同步?

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • Dora.Interception: 一个为.NET Core度身定制的AOP框架 - Artech

    Dora.Interception: 一个为.NET Core度身定制的AOP框架 - Artech

    2017-05-02 11:00

  • 如何在 ASP.NET Core 中发送邮件 - Savorboard

    如何在 ASP.NET Core 中发送邮件 - Savorboard

    2017-05-02 08:02

  • vue全局配置----小白基础篇 - 星光笔

    vue全局配置----小白基础篇 - 星光笔

    2017-04-28 08:04

  • 十二个 ASP.NET Core 例子 - Savorboard

    十二个 ASP.NET Core 例子 - Savorboard

    2017-04-27 16:01

网友点评
<