C# Monitor与线程同步

  Monitor对象(C#知识点总结系列:4、C#中Monitor和Lock以及区别)

  1.Monitor.Enter(object)方法是获取锁,Monitor.Exit(object)方法是释放锁,这就是Monitor最常用的两个方法,当然在使用过程中为了避免获取锁之后因为异常,致锁无法释放,所以需要在try{} catch(){}之后的finally{}结构体中释放锁(Monitor.Exit())。

  2.Monitor的常用属性和方法:

    Enter(Object) 在指定对象上获取排他锁。

    Exit(Object) 释放指定对象上的排他锁。

    IsEntered 确定当前线程是否保留指定对象锁。

    Pulse 通知等待队列中的线程锁定对象状态的更改。

    PulseAll 通知所有的等待线程对象状态的更改。

    TryEnter(Object) 试图获取指定对象的排他锁。

    TryEnter(Object, Boolean) 尝试获取指定对象上的排他锁,并自动设置一个值,指示是否得到了该锁。

    Wait(Object) 释放对象上的锁并阻止当前线程,直到它重新获取该锁。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

//线程同步与多线程程序中的隐患
namespace Multithreading_hazard
{
    class Program
    {
        private static int stickets = 100;
        static  object gloalObj=new object();//辅助对象
        static void Main(string[] args)
        {
            Thread thread1 = new Thread(SaleTicketThread1);
            Thread thread2 = new Thread(SaleTicketThread2);
            thread1.Start();
            thread2.Start();
            Thread.Sleep(4000);
        }

        private static void SaleTicketThread1()
        {
            while (true)
            {
                try
                {
                    Monitor.Enter(gloalObj);//在gloalObj对象上获得排他锁
                    Thread.Sleep(1);
                    if (stickets > 0)
                    {
                        Console.WriteLine("线程一出票{0}:", stickets--);
                    }
                    else
                    {
                        break;
                    }
                }
                finally 
                {
                    
                    Monitor.Exit(gloalObj);//释放指定对象上的排他锁
                }
                
            }
        }
        private static void SaleTicketThread2()
        {
            while (true)
            {

                try
                {
                    Monitor.Enter(gloalObj);//在gloalObj对象上获得排他锁
                    Thread.Sleep(1);
                    if (stickets > 0)
                    {
                        Console.WriteLine("线程二出票{0}:", stickets--);
                    }
                    else
                    {
                        break;
                    }
                }
                finally
                {

                    Monitor.Exit(gloalObj);//释放指定对象上的排他锁
                }
            }
        }
    }

}

 

利用Monitor的Enter(Object) 、Exit(Object)实现了线程同步,一个线程将等待前一个线程执行完成后,才继续执行

posted @ 2017-08-07 13:08  LBO.net  阅读(376)  评论(0编辑  收藏  举报
//返回顶部