线程同步,一般来说分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);//释放锁 } } } } }