多线程同步_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(1000);

//trTwo启动线程
trTwo.Name = "trTwo";
trTwo.Start(trTwo.Name);

Console.Read();
}
}

class ThredDemo
{
public List<int> obj;
int i = 0;

public ThredDemo()
{
obj = new List<int>();
}

public void TrOne(object thredName)
{
//相当于lock 参考TrTwo
Monitor.Enter(obj);

Console.WriteLine("1");
// TrOne释放对象上的锁并阻止当前线程这个时候TrTwo启动并进入临界区
Monitor.Wait(obj);

Console.WriteLine("2");
Console.WriteLine("线程{0}正在执行......i的值{1}", thredName.ToString(),i);

i++;
Monitor.Pulse(obj);
Console.WriteLine("3");

//TrOne进入等待
Monitor.Wait(obj);
Monitor.Exit(obj);
Console.WriteLine("4");
}

public void TrTwo(object thredName)
{
lock (obj)
{
//TrTwo通过Wait 释放进入 这个时候TrOne阻塞i的值++
Console.WriteLine("5");
i++;

//释放等待的(Wait)的线程 并马上自己阻塞等待TrOne Pulse
Monitor.Pulse(obj);

Console.WriteLine("6");

Monitor.Wait(obj);
Console.WriteLine("线程{0}正在执行......i的值{1}", thredName.ToString(), i);

//释放 这样console输出的4一定在7的后面 因为TrOne阻塞需要TrTwo释放 当前前提是程序无BUG
Monitor.Pulse(obj); -----标记
Console.WriteLine("7");
}
}
}
}

为了方便理解自己加入输入查看效果 .

结果:

如果我把 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(1000);

//trTwo启动线程
trTwo.Name = "trTwo";
trTwo.Start(trTwo.Name);

Console.Read();
}
}

class ThredDemo
{
public List<int> obj;
int i = 0;

public ThredDemo()
{
obj = new List<int>();
}

public void TrOne(object thredName)
{
//相当于lock 参考TrTwo
Monitor.Enter(obj);

Console.WriteLine("1");
// TrOne释放对象上的锁并阻止当前线程这个时候TrTwo启动并进入临界区
Monitor.Wait(obj);

Console.WriteLine("2");
Console.WriteLine("线程{0}正在执行......i的值{1}", thredName.ToString(),i);

i++;
Monitor.Pulse(obj);
Console.WriteLine("3");

//TrOne进入等待 1分钟后 注意的是
// 如果指定的超时间隔已过,则线程进入就绪队列。
Monitor.Wait(obj,60000);
Monitor.Exit(obj);
Console.WriteLine("4");
}

public void TrTwo(object thredName)
{
lock (obj)
{
//TrTwo通过Wait 释放进入 这个时候TrOne阻塞i的值++
Console.WriteLine("5");
i++;

//释放等待的(Wait)的线程 并马上自己阻塞等待TrOne Pulse
Monitor.Pulse(obj);

Console.WriteLine("6");

Monitor.Wait(obj);
Console.WriteLine("线程{0}正在执行......i的值{1}", thredName.ToString(), i);

//释放 这样console输出的4一定在7的后面 因为TrOne阻塞需要TrTwo释放 当前前提是程序无BUG

// Monitor.Pulse(obj);
Console.WriteLine("7");
}
Console.WriteLine("8");
}
}
}

把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,码迷,mamicode.com

时间: 2024-11-06 13:17:11

多线程同步_Monitor的相关文章

Java多线程同步机制

Java的多线程同步机制和其他语言开发的是一样的,在当前线程中,遇到某个事件时,等待另一个线程运行结束或者另一个线程的事件,然后再决定如何处理. 本例来自书上的实例,精简了代码,调整了部分逻辑,使得看起来更加简洁明了.已经运行通过. 代码如下: package SwingExample; import java.awt.BorderLayout; import java.util.Random; import javax.swing.JFrame; import javax.swing.JPro

多线程同步条件变量(转载)

最近看<UNIX环境高级编程>多线程同步,看到他举例说条件变量pthread_cond_t怎么用,愣是没有看懂,只好在网上找了份代码,跑了跑,才弄明白 [cpp] view plaincopy #include <pthread.h> #include <stdio.h> #include <stdlib.h> pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;/*初始化互斥锁*/ pthread_cond_

java基础知识回顾之java Thread类学习(六)--java多线程同步函数用的锁

1.验证同步函数使用的锁----普通方法使用的锁 思路:创建两个线程,同时操作同一个资源,还是用卖票的例子来验证.创建好两个线程t1,t2,t1线程走同步代码块操作tickets,t2,线程走同步函数封装的代码操作tickets,同步代码块中的锁我们可以指定.假设我们事先不知道同步函数用的是什么锁:如果在同步代码块中指定的某个锁(测试)和同步函数用的锁相同,就不会出现线程安全问题,如果锁不相同,就会发生线程安全问题. 看下面的代码:t1线程用的同步锁是obj,t2线程在操作同步函数的资源,假设不

多线程同步程序的测试思路

这里我有一个简单的思路,来源于去年应届生找工作做大量的名企笔试题里他人的技巧. 多线程的测试使用cout是不靠谱的,因为多个线程使用cout很容易产生混乱的输出,而且耗时. 多线程的测试往往需要知道多个线程同时运行的时候对某个共享区域的使用是否正确,为了检验正确性,比较好的测试用例就是:递增的整数序列 递增的整数序列中的每一个整数都对应一个线程的动作,最后我们将这些整数再当成另一个标记数组的下标,下标对应的值就是我们操作的动作执行的次数 只要用于标记的数组每一个元素都是1,即可. 比如: (1)

【python标准库学习】thread,threading(二)多线程同步

继上一篇介绍了python的多线程和基本用法.也说到了python中多线程中的同步锁,这篇就来看看python中的多线程同步问题. 有时候很多个线程同时对一个资源进行修改,这个时候就容易发生错误,看看这个最简单的程序: import thread, time count = 0 def addCount(): global count for i in range(100000): count += 1 for i in range(10): thread.start_new_thread(ad

通过Lock对象以及Condition对象实现多线程同步

通过Lock对象以及Condition对象实现多线程同步: 在之前的学习中,无论是通过synchronized建立同步代码块,还是通过synchronized建立同步函数,都是把对象看成一把锁来实现同步,这种解释有点牵强,而且在消费者-生产者的那个实例中,其实还有个问题,那就是在避免线程全部冻结时,没必要把相同功能的线程解冻,只要把其他功能的线程解冻即可,也就是说消费者线程只要解冻生产者线程即可,没必要把其他消费者线程也解冻,为了解决这些问题,java1.5版本推出了同步的升级办法,那就是通过L

一个经典的多线程同步问题

上一篇<秒杀多线程第三篇原子操作 Interlocked系列函数>中介绍了原子操作在多进程中的作用,现在来个复杂点的.这个问题涉及到线程的同步和互斥,是一道非常有代表性的多线程同步问题,如果能将这个问题搞清楚,那么对多线程同步也就打下了良好的基础. 程序描述: 主线程启动10个子线程并将表示子线程序号的变量地址作为参数传递给子线程.子线程接收参数 -> sleep(50) -> 全局变量++ -> sleep(0) -> 输出参数和全局变量. 要求: 1.子线程输出的线

C# 中 多线程同步退出方案 CancellationTokenSource

C# 中提供多线程同步退出机制,详参对象: CancellationTokenSource CancellationTokenSource 中暂未提供复位操作,因此当调用Cancle 之后,若再次调用,需重新初使化对象. 代码示例: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.

嵌入式 Linux进程间通信(十二)——多线程同步

嵌入式 Linux进程间通信(十二)--多线程同步 多线程编程中有三种线程同步机制:互斥锁.信号量.条件量.本文将使用生产者消费者问题编程实践三种线程同步方式. 生产者.消费者问题:生产者线程生产物品,然后将物品放置在一个空缓冲区中供消费者线程消费.消费者线程从缓冲区中获得物品,然后释放缓冲区.当生产者线程生产物品时,如果没有空缓冲区可用,那么生产者线程必须等待消费者线程释放出一个空缓冲区.当消费者线程消费物品时,如果没有满的缓冲区,那么消费者线程将被阻塞,直到新的物品被生产出来. 一.互斥锁