当多个线程在并发的时候,难免会碰到相互冲突的事情,比如最经典的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);
}
}
}

  

c# monitor锁的更多相关文章

  1. 015-线程同步-synchronized几种加锁方式、Java对象头和Monitor、Mutex Lock、JDK1.6对synchronized锁的优化实现

    一.synchronized概述基本使用 为确保共享变量不会出现并发问题,通常会对修改共享变量的代码块用synchronized加锁,确保同一时刻只有一个线程在修改共享变量,从而避免并发问题. syn ...

  2. 重新想象 Windows 8 Store Apps (46) - 多线程之线程同步: Lock, Monitor, Interlocked, Mutex, ReaderWriterLock

    [源码下载] 重新想象 Windows 8 Store Apps (46) - 多线程之线程同步: Lock, Monitor, Interlocked, Mutex, ReaderWriterLoc ...

  3. 【C#】【Thread】Monitor和Lock

    所谓锁,就是之锁定的区域只能单个线程进入进行操作,其他线程在锁的外围等待.Monitor锁通过Monitor.Enter(obj)和Monitor.Exit(obj)来锁定和解锁.Lock锁则直接Lo ...

  4. 转:【Java并发编程】之七:使用synchronized获取互斥锁的几点说明

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/17199201     在并发编程中,多线程同时并发访问的资源叫做临界资源,当多个线程同时访 ...

  5. 深入介绍Java中的锁[原理、锁优化、CAS、AQS]

    1.为什么要用锁? 锁-是为了解决并发操作引起的脏读.数据不一致的问题. 2.锁实现的基本原理 2.1.volatile Java编程语言允许线程访问共享变量, 为了确保共享变量能被准确和一致地更新, ...

  6. 线程安全(中)--彻底搞懂synchronized(从偏向锁到重量级锁)

    接触过线程安全的同学想必都使用过synchronized这个关键字,在java同步代码快中,synchronized的使用方式无非有两个: 通过对一个对象进行加锁来实现同步,如下面代码. synchr ...

  7. 转 : 深入解析Java锁机制

    深入解析Java锁机制 https://mp.weixin.qq.com/s?__biz=MzU0OTE4MzYzMw%3D%3D&mid=2247485524&idx=1&s ...

  8. java 偏向锁、轻量级锁及重量级锁synchronized原理

    Java对象头与Monitor java对象头是实现synchronized的锁对象的基础,synchronized使用的锁对象是存储在Java对象头里的. 对象头包含两部分:Mark Word 和 ...

  9. Java 线程与锁

    Synchronization synchronized语法可以获取锁, 当其他线程持有锁的时候该线程想要获取锁将会进入等待状态, 直到没有其他线程持有该锁 显示使用 synchronized (lo ...

随机推荐

  1. docker summary

    http://blog.tankywoo.com/docker/2014/05/08/docker-4-summary.html 总结的很好 ----------------------------- ...

  2. transient关键字的含义

    transient java语言的关键字,变量修饰符,如果用transient声明一个实例变量,当对象存储时,它的值不需要维持. Java的serialization提供了一种持久化对象实例的机制.当 ...

  3. Swift游戏实战-跑酷熊猫 10 视差滚动背景

    原理 实现 勘误 “实现”的视频中有个错误,如下 背景移动时有个错误,看红色部分,近景归位时,第二张图片的下标是1 if arrBG[0].position.x + arrBG[0].frame.wi ...

  4. Codeforce Round #211 Div2

    真的是b到不行啊! 尼玛C题一个这么简单的题目没出 aabbccddee 正确的是aabccdee 我的是   aabcdee 硬是TM的不够用,想半天还以为自己的是对的... A:题... B:题. ...

  5. 强连通+二分匹配(hdu4685 Prince and Princess)

    Prince and Princess Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Othe ...

  6. [转]关于安装hadoop中出现的的 $HADOOP_HOME is deprecated 的解决方法

    当前用户的.bash_profile在/home/用户/下,系统的.bash_profile在/etc/skel目录下; 默认可能是隐藏的:有人会问了,隐藏的我怎么打开它,一个简单的办法,直接使用vi ...

  7. angular Creating a Directive that Adds Event Listeners

    <span my-draggable>Drag ME</span> angular.module('dragModule', []) .directive('myDraggab ...

  8. Oracle游标总结

    1.声明游标 declare teacher_id ); teacher_name ); teacher_title ); teacher_sex ); cursor teacher_cur is ; ...

  9. 20道C#练习题(一)1——10题

    1.输入三个整数,xyz,最终以从小到大的方式输出.利用if嵌套. Console.Write("请输入x="); double x = double.Parse(Console. ...

  10. InstallShield 下载安装

    好久没有写项目了,昨晚加班给一位淘客写了一个Winform小程序, 今早发布,然后发现微软将软件发布的这块内容交给了一个第三方插件 InstallShield, 不知道微软是何用意,我们还是看看如何安 ...