大家好,我在学习C#多线程编程时遇到了下面的问题。
我建立了三个线程,一个生产者Producer和两个消费者Consumer,在HoldIntegerSync的内部对多线程读取与写入进行同步,但是为什么我在HoldIntegerSync的get和set中的lock锁定不起作用呢?所有线程都能同时进入被lock包裹的代码。using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;namespace ConsoleApplication2
{
public class Program
{
static void Main(string[] args)
{
Console.WriteLine("Main Start."); try
{
HoldIntegerSync his = new HoldIntegerSync();
Consumer consumer = new Consumer(his);
Consumer consumerTwo = new Consumer(his); Producer producer = new Producer(his); Thread producerThread = new Thread(new ThreadStart(producer.Produce));
producerThread.Name = "Producer"; Thread consumerThread1 = new Thread(new ThreadStart(consumer.Consume));
consumerThread1.Name = "Consumer"; Thread consumerThread2 = new Thread(new ThreadStart(consumerTwo.Consume));
consumerThread2.Name = "ConsumerTwo"; consumerThread1.Start();
consumerThread2.Start();
producerThread.Start(); }
catch (Exception e)
{
Console.WriteLine("Catch Exception : \n" + e.ToString()); Console.WriteLine("Exception Message : \n" + e.Message); Console.WriteLine("Exception Inner :\n" + e.InnerException);
} Console.WriteLine("Main End.");
}
} class Producer
{
private Random rd = new Random(10);
private HoldIntegerSync sync;
public Producer(HoldIntegerSync his)
{
this.sync = his;
} public void Produce()
{
sync.Buffer = rd.Next();
}
} class Consumer
{
private HoldIntegerSync sync;
public Consumer(HoldIntegerSync his)
{
this.sync = his;
} public void Consume()
{
Console.WriteLine(Thread.CurrentThread.Name + " read: {0}", sync.Buffer);
}
} class HoldIntegerSync
{
private int count = 0; private int _Buffer; public int Buffer
{
get
{
lock (this)
{
Console.WriteLine(Thread.CurrentThread.Name + " Enter lock.");
if (count == 0)
{
Console.WriteLine(Thread.CurrentThread.Name + " waiting read.");
Monitor.Wait(this);
} Console.WriteLine(Thread.CurrentThread.Name + " reading:{0}", _Buffer); count--; Monitor.PulseAll(this);
} Console.WriteLine(Thread.CurrentThread.Name + " Exit lock."); return _Buffer;
} set
{
lock (this)
{
Console.WriteLine(Thread.CurrentThread.Name + " Enter lock");
if (count == 1)
{
Console.WriteLine(Thread.CurrentThread.Name + " waiting write.");
Monitor.Wait(this);
} Console.WriteLine(Thread.CurrentThread.Name + " writing:{0}", value); _Buffer = value; count++; Monitor.PulseAll(this);
} Console.WriteLine(Thread.CurrentThread.Name + " Exit lock.");
}
}
}}
我建立了三个线程,一个生产者Producer和两个消费者Consumer,在HoldIntegerSync的内部对多线程读取与写入进行同步,但是为什么我在HoldIntegerSync的get和set中的lock锁定不起作用呢?所有线程都能同时进入被lock包裹的代码。using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;namespace ConsoleApplication2
{
public class Program
{
static void Main(string[] args)
{
Console.WriteLine("Main Start."); try
{
HoldIntegerSync his = new HoldIntegerSync();
Consumer consumer = new Consumer(his);
Consumer consumerTwo = new Consumer(his); Producer producer = new Producer(his); Thread producerThread = new Thread(new ThreadStart(producer.Produce));
producerThread.Name = "Producer"; Thread consumerThread1 = new Thread(new ThreadStart(consumer.Consume));
consumerThread1.Name = "Consumer"; Thread consumerThread2 = new Thread(new ThreadStart(consumerTwo.Consume));
consumerThread2.Name = "ConsumerTwo"; consumerThread1.Start();
consumerThread2.Start();
producerThread.Start(); }
catch (Exception e)
{
Console.WriteLine("Catch Exception : \n" + e.ToString()); Console.WriteLine("Exception Message : \n" + e.Message); Console.WriteLine("Exception Inner :\n" + e.InnerException);
} Console.WriteLine("Main End.");
}
} class Producer
{
private Random rd = new Random(10);
private HoldIntegerSync sync;
public Producer(HoldIntegerSync his)
{
this.sync = his;
} public void Produce()
{
sync.Buffer = rd.Next();
}
} class Consumer
{
private HoldIntegerSync sync;
public Consumer(HoldIntegerSync his)
{
this.sync = his;
} public void Consume()
{
Console.WriteLine(Thread.CurrentThread.Name + " read: {0}", sync.Buffer);
}
} class HoldIntegerSync
{
private int count = 0; private int _Buffer; public int Buffer
{
get
{
lock (this)
{
Console.WriteLine(Thread.CurrentThread.Name + " Enter lock.");
if (count == 0)
{
Console.WriteLine(Thread.CurrentThread.Name + " waiting read.");
Monitor.Wait(this);
} Console.WriteLine(Thread.CurrentThread.Name + " reading:{0}", _Buffer); count--; Monitor.PulseAll(this);
} Console.WriteLine(Thread.CurrentThread.Name + " Exit lock."); return _Buffer;
} set
{
lock (this)
{
Console.WriteLine(Thread.CurrentThread.Name + " Enter lock");
if (count == 1)
{
Console.WriteLine(Thread.CurrentThread.Name + " waiting write.");
Monitor.Wait(this);
} Console.WriteLine(Thread.CurrentThread.Name + " writing:{0}", value); _Buffer = value; count++; Monitor.PulseAll(this);
} Console.WriteLine(Thread.CurrentThread.Name + " Exit lock.");
}
}
}}
解决方案 »
- c#中 从数据库提取图片的问题
- C#中怎么实现vector一样的功能
- C# 备份远程数据库
- WinFrom 控件绑定右键菜单
- 想提取出一段文本中所有的IP地址 数字.数字.数字.数字,如何做?
- 在C#中如何将文本文件写成编码方式为ANSI类型的!知道的谢谢了!急
- Label控件的背景怎么变成透明的,就像VB6一样
- .ASPX 遇到繁体WIN7,提交中文字串数据库出现乱码
- 求一组数的连续的数的个数???
- C#做WEB程序怎样将存在SQL的图片显示到DATAGRID里?大家再帮帮忙了!
- 支付宝支付成功后跳转到指定页接收参数的问题
- Nhibernate Named Query 问题(100分,分不够在加)
释放对象上的锁并阻止当前线程,直到它重新获取该锁。
{
//do something
}
完全等价于下面的代码:
try
{
Moniter.Enter(object);
//do something
}
catch{}
finnaly
{
Moniter.Exit(object);
}你在lock块中,使用了Monitor.Wait(object)方法,等于已暂时释放了锁,其他线程当然可以进入了