only .Net技术

coding by c# only...................
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

声明、本人也是初次接触线程,写此文章只为分享学习经验,并无它意。

 

1、为什么说是改进版?

原文是实现功呢是两个线程同时操作一个数据

一个线程操作完毕,释放锁,另一个线程操作,释放锁,循环直到程序结束

使用的等待方法是


为了达到举一反三的效果,特把原来程序改为

一个线程等待另外两个线程全部完毕后执行操作

并且使用 Wait(Object) 方法

并且写有相关提示,使阅读代码者能够了解线程的执行方法

2、先给出源代码

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

using System.Threading;

namespace ThreadMonitorDemo
{

    
class MonitorClass
    
{
        
private int n = 1;
        
private int m = 1;
        
private int max = 10;

        
private object createrN = new object();
        
private object craeterM = new object();

        
public void ProduceN()
        
{
            
lock (createrN)
            
{
                
for (; n < max; n++)
                
{
                    Console.WriteLine(
"释放 n=" + n.ToString());
                    
//Monitor.Pulse(createrN);
                    bool isReleaseN = Monitor.Wait(createrN);
                    Console.WriteLine(
"Consume 调用方重新获取了createrN的锁  " + isReleaseN.ToString());
                }

            }

            Console.WriteLine(
"ProduceN Run Over");
        }


        
public void ProduceM()
        
{
            
lock (craeterM)
            
{
                
for (; m < max; m++)
                
{
                    Console.WriteLine(
"释放 m=" + m.ToString());
                    
//Monitor.Pulse(craeterM);
                    bool isReleaseM = Monitor.Wait(craeterM);
                    Console.WriteLine(
"Consume 重新获取了createrM 的锁   " + isReleaseM.ToString());
                }

            }

            Console.WriteLine(
"ProduceM Run Over");
        }



        
public void Consume()
        
{
            
lock (createrN)
            
{
                
lock (craeterM)
                
{
                    
while (m < max && n < max)
                    
{
                        Console.WriteLine(
"接收 n=" + n.ToString() + "  m=" + m.ToString());
                        Monitor.Pulse(craeterM);
                        
//Monitor.Wait(craeterM);
                        bool isReleaseM =  Monitor.Wait(craeterM, 500);
                        Console.WriteLine(
"ProduceM 重新获取了craeterM的锁  " + isReleaseM.ToString());

                        Monitor.Pulse(createrN);
                        
//Monitor.Wait(createrN);
                        bool isReleaseN = Monitor.Wait(createrN, 500);
                        Console.WriteLine(
"ProduceN 重新获取了createrN 的锁   " + isReleaseN.ToString());

                    }

                }

            }

            Console.WriteLine(
"Consume Run Over");
        }

    }


    
class Program
    
{
        
static void Main(string[] args)
        
{
            MonitorClass m 
= new MonitorClass();

            Thread tProduce 
= new Thread(new ThreadStart(m.ProduceN));
            Thread tProduceM 
= new Thread(new ThreadStart(m.ProduceM));
            Thread tConsume 
= new Thread(new ThreadStart(m.Consume));

            tProduce.Start();
            tProduceM.Start();
            tConsume.Start();

            Console.ReadLine();
        }

    }

}

3、介绍一下对Monitor类的一点小的看法

Monitor类从字面意思看是一个监视器,其实它的每次操作也是单独的一个线程

等于是几个线程同时工作,中间由Monitor类来协调工作先后次序、以及帮助线程间传递消息,算是个指挥官的角色

并且MonitorWait 方法 是有返回值的Msdn上是真样说的

如果调用由于调用方重新获取了指定对象的锁而返回,则为 true。如果未重新获取该锁,则此方法不会返回。

我的理解是,如果其他线程获取了该对象的锁并且显示的通过 Monitor.Pulse(object obj)方法进行对其它等待线程的通知返回 true

否则返回false

原因:当我不进行显示脉冲通知的时候执行结果是这样的

 

并且每次执行时等待500毫秒

进行通知 取消Monitor.Pulse(craeterM); 前面的注释 后的执行结果是


 

每次执行 Monitor..::.Wait 方法  返回的都是true

并且中间时间没有等待间隔

好像只有最后一次有


所以说Monitor。Wait 方法的返回值我们可以这样理解

如果其他线程获取了该对象的锁并且显示的通过 Monitor.Pulse(object obj)方法进行对其它等待线程的通知返回 true

否则返回false

 

4、根据代码执行结果分析程序的执行顺序

 

 

说着不清楚所以画了张图

大家跟着程序执行的顺序应该能够看得清楚

 

这张图说明了程序执行的顺序,同时也说明了 Monitor 对象是由自己一个单独的线程进行控制的,起着调节的作用

 

 

但是刚才好像还是有个问题就是

 

在Consume()中使用超时等待模式isReleaseM = Monitor.Wait(craeterM, 1000);时

 

有最后一次出现等待现象

 

是什么原因呢???


暂时没有搞明白。。。。

 

原文作者 陈晨 有兴趣的话可以一起研究

 

好,就到这儿了


希望大家批评斧正、、

 

源码  ThreadMonitorDemo2008-07-31.rar