zoukankan      html  css  js  c++  java
  • 【C#】【Thread】Monitor和Lock

    所谓锁,就是之锁定的区域只能单个线程进入进行操作,其他线程在锁的外围等待。
    Monitor锁通过Monitor.Enter(obj)和Monitor.Exit(obj)来锁定和解锁。
    Lock锁则直接Lock(obj)进行锁定。
    Monitor锁和Lock锁很类似,实质Lock锁是Monitor的变体。
    lock(obj)
    {
    }
    等价为:
    try
    {    
       Monitor.Enter(obj) 
    }
    catch()
    {}
    finally
    {
       Monitor.Exit(obj) 
    }
    所以lock能做的,Monitor肯定能做,Monitor能做的,lock不一定能做。
    下面讲一下Monitor的特殊与Lock功能。
    Monitor.Enter(obj);// 启动锁
    Monitor.TryEnter(obj, 1000);//启动锁,也是区别于Lock的功能,多了一个时间设置,就是等待多少时间后如果还不能进入,则取消此次操作。Lock则会一直等待下去。
    Monitor.Wait(obj);// 会放弃当前线程对资源的所有权,让别的线程到lock进来。然后当别的线程代码里Pulse一下(让原线程进入到等待队列),之后从Waint()后面继续运行下去
    Monitor.Pulse(obj);// 恢复原放弃资源控制权的线程,使其重新进入到等待队列中,下次直接从Wait()后继续运行。
    Monitor.PulseAll(obj);// 恢复所有曾今放弃资源控制权的线程,使其重新进入到等待队列中
    Monitor.Exit(obj);
    // 结束锁
    例子:
            [MethodImpl(MethodImplOptions.Synchronized)]
            private void FirstThread()
            {
                //Monitor.Enter(this);
                Monitor.Wait(this);
                MessageBox.Show("FirstThread");
                //Monitor.Exit(this);
            }
            private void SecondThread()
            {
                Monitor.Enter(this);
                Monitor.Wait(this);
                MessageBox.Show("SecondThread");
                Monitor.Pulse(this);
                Monitor.Exit(this);
            }
            private void ThirdThread()
            {
                Monitor.Enter(this);
                MessageBox.Show("ThirdThread");
                Monitor.Pulse(this);
                Monitor.Exit(this);
            }

    调用:

    Thread thread = new Thread(new ThreadStart(FirstThread));
    thread.Name = "thread1";
    Thread thread2 = new Thread(new ThreadStart(SecondThread));
    hread2.Name = "thread2";
    Thread thread3 = new Thread(new ThreadStart(ThirdThread));
    thread3.Name = "thread3";
    thread.Start(); 
    thread2.Start();
    thread3.Start();

    运行结果:

    首先线程会进入到FirstThread方法,然后因为Wait了,所以线程1放弃所有权,然后线程2进入SecondThread,因为也Wait了,所以线程3进入ThirdThread,然后会MessageBox弹出“TirdThread”,之后运行Pulse,所以释放了线程2,所以线程2会MessageBox弹出“SecondThread”,之后再释放线程1弹出“FirstThread”。

    每一个锁都必须要有Enter和Exit,里面参数是一个Object类型,是一个锁的标识。

    在这FirstThread方法中没有使用Enter和Exit而是使用了

    [MethodImpl(MethodImplOptions.Synchronized)]
    这个作用相当于在这个方法开始和结尾处分别加上了Enter和Exit。

  • 相关阅读:
    Ubuntu 12.04下GAMIT10.40安装说明
    GAMIT 10.50在Ubuntu 12.04系统下的安装
    tomcat 5.5 动态加载类
    GAMIT 10.50在Ubuntu 12.04系统下的安装
    RHCE 系列(九):如何使用无客户端配置 Postfix
    Nginx+Keepalived(带Nginx监控脚本)
    黑马程序员_java08_多线程
    oracle 表类型变量的使用
    如何在win7系统中安装redis
    bzoj 2816: [ZJOI2012]网络(splay)
  • 原文地址:https://www.cnblogs.com/mqxs/p/4639367.html
Copyright © 2011-2022 走看看