• 线程同步详解


    线程同步,一般来说分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);//释放锁
                    }
                }
            }
        }
    }
  • 相关阅读:
    車(rook)
    那些年,我们学过的文化课
    皇后(queen)
    蚂蚁运输(ant)
    [Z]CS权威会议
    [Z] 北大一牛人生物转申CS的经历
    TLS协议扫盲(握手,非对称加密,证书,电子签名等)
    关于SSE的一些资料
    Java下LDAP操作的资料
    [Z] Windbg以及vs debug使用
  • 原文地址:https://www.cnblogs.com/tibos/p/5354131.html
Copyright © 2020-2023  润新知