墨染白青

越努力越幸运 一枚专心撸码的女程序猿

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

(原文地址:https://www.cnblogs.com/tibos/p/5354131.html)

线程同步,一般来说分2种情况:

1.锁互斥

线程A在访问某个对象时,禁止其它线程访问,保证线程里的function为最小核心级.

2.信号灯

A线程执行完唤醒B线程,B线程执行完,唤醒A,反复交替,输出A1B1A2B2....A100B100

 Monitor.Enter(m_monitorObject);//获得锁

 Monitor.Exit(m_monitorObject);//释放锁

m_monitorObject为一个object对象,(如果只值类型,则造成死锁)

重点来说信号灯

这里我引入ManualResetEvent对象,ManualResetEvent.WaitOne(100, false),这里我阻塞线程100毫秒,如为-1则无休止阻塞.

ManualResetEvent.Reset(),将线程设置为非终止状态,阻塞线程.

ManualResetEvent.Set();唤醒线程

通过这三个方法,就可以简单的实现信号灯功能.

这里附上源码:

复制代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        /// <summary>
        /// 线程同步
        /// 1.保证子线程里面的function为最小"原子级"
        /// 2.线程的等待与唤醒
        /// PS:这里主要用到2
        /// </summary>
        public Thread thA,thB,thC;
        private static ManualResetEvent eventOver = new ManualResetEvent(false);
        private static ManualResetEvent eventWait = new ManualResetEvent(false);
        private static ManualResetEvent eventThree = new ManualResetEvent(false);
        private void button1_Click(object sender, EventArgs e)
        {
            CheckForIllegalCrossThreadCalls = false;
            thA = new Thread(new ThreadStart(printA));
            thB = new Thread(new ThreadStart(printB));
            thC = new Thread(new ThreadStart(printC));
            thA.Name = "线程A";
            thB.Name = "线程B";
            thC.Name = "线程C";
            thA.Start();
            thB.Start();
            thC.Start();
            thA.Join();
            thB.Join();
            thC.Join();
        }
        private static object m_monitorObject = new object();
        public void printA()
        {
            for (int i = 0; i < 1000; i++)
            {
                if (eventOver.WaitOne(100, false))//线程A处于阻塞状态,等待唤醒
                {
                    Monitor.Enter(m_monitorObject);//获得锁
                    this.lbxShow.Items.Add(Thread.CurrentThread.Name + i);
                    eventOver.Reset();//线程A阻塞
                    eventWait.Set();//唤醒线程B
                    Monitor.Exit(m_monitorObject);//释放锁
                }
            }
        }
        public void printB()
        {
            eventOver.Set();//先唤醒A
            for (int i = 0; i < 1000; i++)
            {
                if (eventWait.WaitOne(100, false))//线程B处于阻塞状态,等待唤醒
                {
                    Monitor.Enter(m_monitorObject);//获得锁
                    this.lbxShow.Items.Add(Thread.CurrentThread.Name + i);
                    eventWait.Reset();//线程B阻塞
                    eventThree.Set();//唤醒线程C
                    Monitor.Exit(m_monitorObject);//释放锁
                }
            }
        }

        public void printC()
        {
            for (int i = 0; i < 1000; i++)
            {
                if (eventThree.WaitOne(100, false))//线程C处于阻塞状态,等待唤醒
                {
                    Monitor.Enter(m_monitorObject);//获得锁
                    this.lbxShow.Items.Add(Thread.CurrentThread.Name + i);
                    eventThree.Reset();//线程C阻塞
                    eventOver.Set();//唤醒线程A
                    Monitor.Exit(m_monitorObject);//释放锁
                }
            }
        }
    }
}
posted on 2019-03-25 11:29  墨染白青  阅读(140)  评论(0编辑  收藏  举报