(转)线程同步详解
(原文地址:https://www.cnblogs.com/tibos/p/5354131.html)
線程同步,一般來說分2種情況:
1.鎖互斥
線程A在訪問某個對象時,禁止其它線程訪問,保證線程里的function為最小核心級.
2.信號燈
A線程執(zhí)行完喚醒B線程,B線程執(zhí)行完,喚醒A,反復交替,輸出A1B1A2B2....A100B100
?Monitor.Enter(m_monitorObject);//獲得鎖
?Monitor.Exit(m_monitorObject);//釋放鎖
m_monitorObject為一個object對象,(如果只值類型,則造成死鎖)
重點來說信號燈
這里我引入ManualResetEvent對象,ManualResetEvent.WaitOne(100, false),這里我阻塞線程100毫秒,如為-1則無休止阻塞.
ManualResetEvent.Reset(),將線程設(shè)置為非終止狀態(tài),阻塞線程.
ManualResetEvent.Set();喚醒線程
通過這三個方法,就可以簡單的實現(xiàn)信號燈功能.
這里附上源碼:
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處于阻塞狀態(tài),等待喚醒{Monitor.Enter(m_monitorObject);//獲得鎖this.lbxShow.Items.Add(Thread.CurrentThread.Name + i);eventOver.Reset();//線程A阻塞eventWait.Set();//喚醒線程BMonitor.Exit(m_monitorObject);//釋放鎖}}}public void printB(){eventOver.Set();//先喚醒Afor (int i = 0; i < 1000; i++){if (eventWait.WaitOne(100, false))//線程B處于阻塞狀態(tài),等待喚醒{Monitor.Enter(m_monitorObject);//獲得鎖this.lbxShow.Items.Add(Thread.CurrentThread.Name + i);eventWait.Reset();//線程B阻塞eventThree.Set();//喚醒線程CMonitor.Exit(m_monitorObject);//釋放鎖}}}public void printC(){for (int i = 0; i < 1000; i++){if (eventThree.WaitOne(100, false))//線程C處于阻塞狀態(tài),等待喚醒{Monitor.Enter(m_monitorObject);//獲得鎖this.lbxShow.Items.Add(Thread.CurrentThread.Name + i);eventThree.Reset();//線程C阻塞eventOver.Set();//喚醒線程AMonitor.Exit(m_monitorObject);//釋放鎖}}}} }轉(zhuǎn)載于:https://www.cnblogs.com/qinmoran123/p/10592757.html
總結(jié)
- 上一篇: day21.模块和包
- 下一篇: JS使用onscroll、scrollT