多线程同步_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& ...
随机推荐
- idea配置2个tomcat
复制tomcat 分别放在不同地方
- oracle 的wm_concat函数使用
转载自:http://blog.itpub.net/post/42245/522757 首先让我们来看看这个神奇的函数wm_concat(列名),该函数可以把列值以","号分隔起来 ...
- 再说vundle: 完全vim字符编程的四个必须插件 - zen coding 和emmet插件的使用
一个常识: 基本上vim插件的配置文集都是放在对应插件目录 的/autoload/ plugin_name.vim 文件中的 有四个必要/必须的插件,实现vim完全的字符界面的编程: NERDTree ...
- 从头开始写框架(一):浅谈JS模块化发展
博客申请下来已经过去一个月了,一直不知道写点什么,毕竟我的文笔不是很好orz. 不过既然申请下来了,不写点什么总是觉得很可惜.正好最近在自己写框架,就把自己的进程和一些心得体会分享出来吧. 写在前面: ...
- 2015年12月03日 GitHub入门学习(五)Markdown语法简介
Markdown一种标记语言,语法简洁,不像Word或Pages有大量排版.字体设置.常用的标记符号不超过十个.被大量写作爱好者.撰稿人.作家所青睐. 一.Markdown的优点 专注你的文字内容而不 ...
- JAVA访问权限控制[zhuan]
Java的访问权限控制修饰符,从最大权限到最小权限依次是:public.protected.包访问权限(默认,没有关键字)和private.对于类的访问权限只能是:public和包访问权限(但内部类可 ...
- 装X之写博客
博客作用: 为了温习以前的知识,记录下 前几天和一个前辈聊天,说起看书总是前面学後面忘点的事情· 写个博客试试?
- 安装SQL Server 2012 『企业中文版』
安装 SQL Server 前,请详细参阅:计划安装SQL Server2012需求详细http://www.cnblogs.com/chhuang/p/3623198.html 安装 SQL Ser ...
- 查看SQL Server日志 Part 1
曾经有朋友问我数据被删除了,不借助第三方工具能不能查是什么时候发生的. SQL Server提供了一个undocumented的函数fn_dblog可以让我们查看活动的transaction log. ...
- JavaScript获取onclick、onchange等事件值的代码
这里主要是用到了getAttributeNode()这个方法,它获取的是属性节点,忽略属性和事件的差别,具体示例如下,感兴趣的朋友可以参考下哈希望对大家有所帮助 今天小菜处理下拉菜单级联问题时,想获取 ...