• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

c#monitor锁

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

   当多个线程在并发的时候,难免会碰到相互冲突的事情,比如最经典的ATM机的问题,并发不可怕,可怕的是我们没有能力控制。

线程以我的理解可以分为三种

① 锁。

② 互斥。

③ 信号。

  好,这一篇主要整理“锁”,C#提供了2种手工控制的锁

一:  Monitor类

     这个算是实现锁机制的纯正类,在锁定的临界区中只允许让一个线程访问,其他线程排队等待。主要整理为2组方法。

 

1:Monitor.Enter和Monitor.Exit

         微软很照护我们,给了我们语法糖Lock,对的,语言糖确实减少了我们不必要的劳动并且让代码更可观,但是如果我们要精细的

     控制,则必须使用原生类,这里要注意一个问题就是“锁住什么”的问题,一般情况下我们锁住的都是静态对象,我们知道静态对象

     属于类级别,当有很多线程共同访问的时候,那个静态对象对多个线程来说是一个,不像实例字段会被认为是多个。

 

 

2:Monitor.Wait和Monitor.Pulse

 首先这两个方法是成对出现,通常使用在Enter,Exit之间。

 Wait: 暂时的释放资源锁,然后该线程进入”等待队列“中,那么自然别的线程就能获取到资源锁。

 Pulse:  唤醒“等待队列”中的线程,那么当时被Wait的线程就重新获取到了锁。






using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace ConsoleApplication3 { class Program { static void Main(string[] args) { for (int i = 0; i < 100; i++) { Thread t = new Thread(run); t.Start(); } Console.ReadKey(); } static object obj = new object(); static int count = 0; static void run() { Thread.Sleep(10); Monitor.Enter(obj); Console.WriteLine(++count); Monitor.Exit(obj); } } }

  

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

namespace Test
{
    public class Program
    {
        public static void Main(string[] args)
        {
            LockObj obj = new LockObj();

            //注意,这里使用的是同一个资源对象obj
            Jack jack = new Jack(obj);
            John john = new John(obj);

            Thread t1 = new Thread(new ThreadStart(jack.Run));
            Thread t2 = new Thread(new ThreadStart(john.Run));

            t1.Start();
            t1.Name = "Jack";

            t2.Start();
            t2.Name = "John";

            Console.ReadLine();
        }
    }

    //锁定对象
    public class LockObj { }

    public class Jack
    {
        private LockObj obj;

        public Jack(LockObj obj)
        {
            this.obj = obj;
        }

        public void Run()
        {
            Monitor.Enter(this.obj);

            Console.WriteLine("{0}:今天我值班吗?看下", Thread.CurrentThread.Name);

            Console.WriteLine("{0}:原来是jon值班呀,那我走呀", Thread.CurrentThread.Name);

            //暂时的释放锁资源
            Monitor.Wait(this.obj);

            Console.WriteLine("{0}:那行吧", Thread.CurrentThread.Name);

            //唤醒等待队列中的线程
            Monitor.Pulse(this.obj);

            Console.WriteLine("{0}:呵呵", Thread.CurrentThread.Name);

            Monitor.Exit(this.obj);
        }
    }

    public class John
    {
        private LockObj obj;

        public John(LockObj obj)
        {
            this.obj = obj;
        }

        public void Run()
        {
            Monitor.Enter(this.obj);

            Console.WriteLine("{0}:哥们,今天我有点事情,你帮我下呗",
                               Thread.CurrentThread.Name);

            //唤醒等待队列中的线程
            Monitor.Pulse(this.obj);

            Console.WriteLine("{0}:谢谢兄弟了", Thread.CurrentThread.Name);

            //暂时的释放锁资源
            Monitor.Wait(this.obj);

            Console.WriteLine("{0}:哈哈", Thread.CurrentThread.Name);

            Monitor.Exit(this.obj);
        }
    }
}

  


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
C#Socketselect模型发布时间:2022-07-10
下一篇:
C#中ToString数据类型格式大全千分符(转)发布时间:2022-07-10
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap