多线程同步_Monitor
多线程一直在学习和理解中......
Monitor类是多线程中用以实现同步的一种技术,主要是同一进程内多线程间的同步技术。
Monitor类中有以下几个方法需要注意:
Monitor.Enter(object obj)方法,其意义相当于Lock(obj);
Monitor.Exit(object obj)方法,意思是释放被锁的对象
Monitor.Wait(object obj)方法,释放被锁的对象,并阻塞当前线程,等待其他线程通知(Pulse)再次获得锁 (个人理解 当前线程 锁 自己也阻塞了 要其他线程唤醒) Monitor.Pulse(object obj)方法,通知等待加锁obj的线程解除阻塞,obj对象状态已经改变(个人理解 唤醒锁住线程 这样锁住线程继续执行 当前方法也继续执行)
注意的是:这两个方法是成对出现,通常使用在Enter,Exit之间。也可以用lock代替
代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading; namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var td = new ThredDemo(); Thread trOne = new Thread(new ParameterizedThreadStart(td.TrOne));
Thread trTwo = new Thread(new ParameterizedThreadStart(td.TrTwo)); //trOne启动线程
trOne.Name = "trOne";
trOne.Start(trOne.Name); //线程睡眠(相当于不参与cpu时间调度,通俗就是卡1000毫秒数)
Thread.Sleep(); //trTwo启动线程
trTwo.Name = "trTwo";
trTwo.Start(trTwo.Name); Console.Read();
}
} class ThredDemo
{
public List<int> obj;
int i = ; public ThredDemo()
{
obj = new List<int>();
} public void TrOne(object thredName)
{
//相当于lock 参考TrTwo
Monitor.Enter(obj); Console.WriteLine("");
// TrOne释放对象上的锁并阻止当前线程这个时候TrTwo启动并进入临界区
Monitor.Wait(obj); Console.WriteLine("");
Console.WriteLine("线程{0}正在执行......i的值{1}", thredName.ToString(),i); i++;
Monitor.Pulse(obj);
Console.WriteLine(""); //TrOne进入等待
Monitor.Wait(obj);
Monitor.Exit(obj);
Console.WriteLine("");
} public void TrTwo(object thredName)
{
lock (obj)
{
//TrTwo通过Wait 释放进入 这个时候TrOne阻塞i的值++
Console.WriteLine("");
i++; //释放等待的(Wait)的线程 并马上自己阻塞等待TrOne Pulse
Monitor.Pulse(obj); Console.WriteLine(""); Monitor.Wait(obj);
Console.WriteLine("线程{0}正在执行......i的值{1}", thredName.ToString(), i); //释放 这样console输出的4一定在7的后面 因为TrOne阻塞需要TrTwo释放 当前前提是程序无BUG
Monitor.Pulse(obj); -----标记
Console.WriteLine("");
}
}
}
}
为了方便理解自己加入输入查看效果 .
结果:

如果我把 TrTwo方法改下
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading; namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var td = new ThredDemo(); Thread trOne = new Thread(new ParameterizedThreadStart(td.TrOne));
Thread trTwo = new Thread(new ParameterizedThreadStart(td.TrTwo)); //trOne启动线程
trOne.Name = "trOne";
trOne.Start(trOne.Name); //线程睡眠(相当于不参与cpu时间调度,通俗就是卡1000毫秒数)
Thread.Sleep(); //trTwo启动线程
trTwo.Name = "trTwo";
trTwo.Start(trTwo.Name); Console.Read();
}
} class ThredDemo
{
public List<int> obj;
int i = ; public ThredDemo()
{
obj = new List<int>();
} public void TrOne(object thredName)
{
//相当于lock 参考TrTwo
Monitor.Enter(obj); Console.WriteLine("");
// TrOne释放对象上的锁并阻止当前线程这个时候TrTwo启动并进入临界区
Monitor.Wait(obj); Console.WriteLine("");
Console.WriteLine("线程{0}正在执行......i的值{1}", thredName.ToString(),i); i++;
Monitor.Pulse(obj);
Console.WriteLine(""); //TrOne进入等待 1分钟后 注意的是
// 如果指定的超时间隔已过,则线程进入就绪队列。
Monitor.Wait(obj,);
Monitor.Exit(obj);
Console.WriteLine("");
} public void TrTwo(object thredName)
{
lock (obj)
{
//TrTwo通过Wait 释放进入 这个时候TrOne阻塞i的值++
Console.WriteLine("");
i++; //释放等待的(Wait)的线程 并马上自己阻塞等待TrOne Pulse
Monitor.Pulse(obj); Console.WriteLine(""); Monitor.Wait(obj);
Console.WriteLine("线程{0}正在执行......i的值{1}", thredName.ToString(), i); //释放 这样console输出的4一定在7的后面 因为TrOne阻塞需要TrTwo释放 当前前提是程序无BUG // Monitor.Pulse(obj);
Console.WriteLine("");
}
Console.WriteLine("");
}
}
}
把Monitor.Pulse(obj);注释掉了 TrOne方法 Monitor.Wait(obj,60000);
运行后 4要等一分钟才输出 原因是 TrTwo方法没有释放 。
个人学习查看过程是 打印输出顺序查看执行过程 这样方便自己理解。
附加线程学习资料(来自博客园 )
逆时针の风 http://www.cnblogs.com/JimmyZheng/archive/2012/06/10/2543143.html
还有一线码农相对 逆时针の风 通俗懂一点
http://www.cnblogs.com/huangxincheng/category/362940.html
以及
黑树
http://www.cnblogs.com/maitian-lf/p/3678128.html
http://www.cnblogs.com/maitian-lf/p/3672390.html
多线程同步_Monitor的更多相关文章
- c#中多线程同步Lock(锁)的研究以及跨线程UI的操作
本文只针对C#中,多线程同步所用到的锁(lock)作为研究对象.由于想更直观的显示结果,所以,在做demo的时候,就把多线程通过事件操作UI的代码也写了出来,留作备忘和分享吧. 其实多线程的同步,使用 ...
- C#多线程同步事件及等待句柄AutoResetEvent 和 ManualResetEvent
最近捣鼓了一下多线程的同步问题,发现其实C#关于多线程同步事件处理还是很灵活,这里主要写一下,自己测试的一些代码,涉及到了AutoResetEvent 和 ManualResetEvent,当然还有也 ...
- C# 中 多线程同步退出方案 CancellationTokenSource
C# 中提供多线程同步退出机制,详参对象: CancellationTokenSource CancellationTokenSource 中暂未提供复位操作,因此当调用Cancle 之后,若再次调用 ...
- Servlet基础(三) Servlet的多线程同步问题
Servlet基础(三) Servlet的多线程同步问题 Servlet/JSP技术和ASP.PHP等相比,由于其多线程运行而具有很高的执行效率. 由于Servlet/JSP默认是以多线程模式执行的, ...
- Linux多线程同步方式
当多个线程共享相同的内存时,需要确保每个线程看到一致的数据视图,当多个线程同时去修改这片内存时,就可能出现偏差,得到与预期不符合的值.为啥需要同步,一件事情逻辑上一定是有序的,即使在并发环境下:而操作 ...
- C# 多线程同步和线程通信
多线程通信 1. 当线程之间有先后的依赖关系时,属于线程之间的通信问题.也就是后一个线程要等待别的一个或多个线程全部完成,才能开始下一步的工作.可以使用: WaitHandle Class WaitH ...
- Java多线程同步问题的探究
一.线程的先来后到——问题的提出:为什么要有多线程同步?Java多线程同步的机制是什么? http://www.blogjava.net/zhangwei217245/archive/2010/03/ ...
- Java多线程同步的方法
一 synchronized关键字 1.synchronized实现原理: ---基于对象监视器(锁) java中所有对象都自动含有单一的锁,JVM负责跟踪对象被加锁的次数.如果一个对象被解锁,其计数 ...
- 多线程同步内功心法——PV操作上(未完待续。。。)
阅读本篇之前推荐阅读以下姊妹篇: <秒杀多线程第四篇一个经典的多线程同步问题> <秒杀多线程第五篇经典线程同步关键段CS> <秒杀多线程第六篇经典线程同步事件Event& ...
随机推荐
- Java并发编程核心方法与框架-exchanger的使用
Exchanger可以使两个线程之间传输数据,比生产者/消费者模式使用wait/notify更加方便. Exchanger中的exchange()方法具有阻塞的特点,此方法被调用后等待其他线程来取数据 ...
- html、css杂记
1:浮动 <div style="float: left"> 2:清除浮动,把父div撑起来 <div style="clear:both"& ...
- Cucumber
http://www.ibm.com/developerworks/library/a-automating-ria/ Cucumber is a testing framework that hel ...
- Ubuntu 源码安装 nginx 1.9.2
安装前准备: //更新系统 1.sudo apt-get update //安装pcre包 2.sudo apt-get install libpcre3 libpcre3-dev 3.sudo ...
- mysql存储过程之异常处理篇
mysql存储过程也提供了对异常处理的功能:通过定义HANDLER来完成异常声明的实现 语法如下: DECLARE handler_type HANDLER FOR condition_value[, ...
- Xcode 历史版本
概述[编辑] Xcode前身是继承自NeXT的Project Builder. The Xcode suite包含有GNU Compiler Collection自由软件(GCC.apple-darw ...
- 《Effective C++》第三版笔记
阅读此笔记前,请先阅读 <Effective C++>第二版笔记 和 <More Effective C++>笔记 这里只记录与上面笔记不同的条款,主要是 "面对 ...
- JDBC:从数据库中取数据的一个bug
先看错误信息: java.sql.SQLException: Before start of result set at com.mysql.jdbc.SQLError.createSQLExcept ...
- Oracle锁的机制
一.为什么要有锁的机制 我们都知道数据库是一个多用户使用的共享资源.当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况.若对并发操作不加控制就可能会读取和存储不正确的数据,破 ...
- js 模块化编程
Javascript模块化编程(一):模块的写法 作者: 阮一峰 日期: 2012年10月26日 随着网站逐渐变成"互联网应用程序",嵌入网页的Javascript代码越来越庞 ...