zoukankan      html  css  js  c++  java
  • (转)线程同步详解

    (原文地址: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);//释放锁
                    }
                }
            }
        }
    }
  • 相关阅读:
    懵懵懂懂的样子
    scrollTop总是为0
    论搜索引擎的重要性
    利用swiper仿iphone时间设置滚轮控件
    厉害了,new Date().getTime()
    invalid Date!iphone上支持的时间格式
    我不知道的MIME
    设置canvas元素的宽高的奇妙(jiujie)发现
    用SVN在github下下载一个文件夹到本地
    c++ md5算法实现(转)
  • 原文地址:https://www.cnblogs.com/qinmoran123/p/10592757.html
Copyright © 2011-2022 走看看