多线程同步,Monitor类

多线程同步

在C#中,可以利用Monitor类等方式实现多线程的同步。Monitor类提供了与lock类相似的共功能,通过向单个线程授予对象锁控制对该对象的访问。Monitor类的Pulse()方法和PulseAll()方法向一个或多个等待的线程发送信号,该信号通知等待线程锁定对的状态已更改,并且锁的所有者准备释放该锁。等待线程被放置在对象的就绪队列中以便最后接收对象锁,一旦线程拥有了锁,就可以检测对象的新状态,以查看是否达到所需状态。Wait()方法则释放对象上的锁以便允许其他线程锁定和访问该对象。在其他线程访问对象时,该调用线程将一直处于等待状态。

例子:生产者消费者问题

生产一个苹果,放在商店中一个,出售一个苹果,商店中苹果少一个,最多生产10个。要求:1、生产者不断将数据放入共享的缓冲;2、消费者不断从共享的缓冲中取出数据;3、生产者必须等消费者取走数据后才能再放新数据(不覆盖数据);4、消费者必须等生产者放入新数据后才能去取(不重复)。

界面

在这里插入图片描述
代码如下所示:

using System.Windows.Forms;
using System.Threading;

namespace Lock
{
    public partial class Form6 : Form
    {
        static object apple = new object();//创建一个互斥体,即苹果对象
        int maxApple = 10;//最大生产数量
        int produceApple = 0;//生产数量
        int consumeApple = 0;//消费数量
        bool flag = false;//标记是否已经生产结束
        Thread tProduce = null;
        Thread tConsume = null;

        public Form6()
        {
            InitializeComponent();
        }

        //生成苹果线程调用
        private void Produce()
        {
            while (!flag)
            {
                lock (apple)
                    for (int i = 1; i <= maxApple; i++)
                    {
                        //生产苹果
                        if (this.InvokeRequired)
                        {
                            this.Invoke(new Action(() =>
                            {
                                this.listBoxProduce.Items.Add(i.ToString());
                            }));
                        }
                        else
                        {
                            this.listBoxProduce.Items.Add(i.ToString());
                        }
                        
                        produceApple++;
                        //生产的苹果放到商店
                        if (this.InvokeRequired)
                        {
                            this.Invoke(new Action(() =>
                            {
                                this.appleStore.Text = produceApple.ToString();
                            }));
                        }
                        else
                        {
                            this.appleStore.Text = produceApple.ToString();
                        }
                       
                        if (i == maxApple)
                        {
                            this.Invoke(new Action(() =>
                            {
                                this.listBoxProduce.Items.Add("苹果生产完了");
                            }));                            
                            flag = true;
                        }
                        Thread.Sleep(500);
                        Monitor.Pulse(apple);
                        Monitor.Wait(apple);
                    }
            }
        }

        //消费苹果线程调用
        private void Consume()
        {
            while (true)
            {
                lock (apple)
                {
                    consumeApple = consumeApple + produceApple;
                    if (this.InvokeRequired)
                    {
                        this.Invoke(new Action(() =>
                        {
                            this.listBoxConsume.Items.Add(consumeApple.ToString());
                        }));
                    }
                    else
                    {
                        this.listBoxConsume.Items.Add(consumeApple.ToString());
                    }
                    
                    produceApple--;
                    if (this.InvokeRequired)
                    {
                        this.Invoke(new Action(() =>
                        {
                        this.appleStore.Text = produceApple.ToString();
                        }));
                    }
                    else
                    {
                        this.appleStore.Text = produceApple.ToString();
                    }
                    if (flag)
                    {
                        if (this.InvokeRequired)
                        {
                            this.Invoke(new Action(() =>
                            {
                                this.listBoxConsume.Items.Add("苹果卖完了");
                            
                            }));
                        }
                        else
                        {
                        this.listBoxConsume.Items.Add("苹果卖完了");                    
                        }
                    }
                    Thread.Sleep(500);
                    Monitor.Pulse(apple);
                    Monitor.Wait(apple);
                }
            }
        }
        private void btn_Start_Click(object sender, EventArgs e)
        {
            tProduce = new Thread(new ThreadStart(Produce));
            tConsume = new Thread(new ThreadStart(Consume)); ;
            tProduce.Start();
            tConsume.Start();
            btn_Start.Enabled = false;
            btn_Stop.Enabled = true;
        }

        private void btn_Stop_Click(object sender, EventArgs e)
        {
            tProduce.Abort();
            tConsume.Abort();
            btn_Start.Enabled = true;
            btn_Stop.Enabled = false;
            this.listBoxProduce.Items.Clear();
            this.listBoxConsume.Items.Clear();
            this.appleStore.Text = "0";
            flag = false;
            produceApple = 0;
            consumeApple = 0;
        }

        private void Form6_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (tProduce != null)
            { tProduce.Abort(); }
            if (tConsume != null)
            {
                { tConsume.Abort(); }
            }
        }
    }
}

运行效果

在这里插入图片描述

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值