博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
(转)线程同步详解
阅读量:5278 次
发布时间:2019-06-14

本文共 3375 字,大约阅读时间需要 11 分钟。

(原文地址: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();        }        ///         /// 线程同步        /// 1.保证子线程里面的function为最小"原子级"        /// 2.线程的等待与唤醒        /// PS:这里主要用到2        ///         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);//释放锁                }            }        }    }}

转载于:https://www.cnblogs.com/qinmoran123/p/10592757.html

你可能感兴趣的文章
分布式计算开源框架Hadoop介绍
查看>>
安卓平台接口剖析
查看>>
坏的事情不都会带来坏的结果
查看>>
RPC的基础:调研EOS插件http_plugin
查看>>
第二次团队冲刺第二天
查看>>
bzoj 2257 (JSOI 2009) 瓶子与燃料
查看>>
11)Java abstract class 和 interface
查看>>
使用xrdp或Xmanager 远程连接 CentOS6
查看>>
Linux误删恢复
查看>>
Unity调用Windows窗口句柄,选择文件和目录
查看>>
HashMap循环遍历方式
查看>>
React Native 入门 调试项目
查看>>
C# 通过 Quartz .NET 实现 schedule job 的处理
查看>>
关于java之socket输入流输出流可否放在不同的线程里进行处理
查看>>
目前为止用过的最好的Json互转工具类ConvertJson
查看>>
Day13
查看>>
tensorflow saver简介+Demo with linear-model
查看>>
Luogu_4103 [HEOI2014]大工程
查看>>
Oracle——SQL基础
查看>>
项目置顶随笔
查看>>