using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;ide
namespace 线程同步问题
{
class Program
{
/// <summary>
/// 首先声明一个事件类,其实是这样的用这个类的实例对象去控制两个线程之间的同步。原理是这样的这个对象有两种状态,若是这个对象是终止状态和非终止状态。若是这个对象是终止状态,
/// 那这个对象调用其等待状态时候,调用waitone时阻塞被当即释放,也就是没有起到阻塞的做用;而后由于这个对象模式是autoReset;因此这个对象会被置为非终止状态。
/// 因此此次再调用阻塞方法,那就会阻塞这个线程。
/// 疑问:
/// autoReset是说被释放一次后会根据模式决定是不是在非终止状态。其实是对释放后状态的判断。
/// waitone:若是是被置为终止状态,线程被永远执行,执行开始后被置为非终止状态。等待下一次被阻塞。
/// 疑问:什么状况下会阻塞线程。什么状况下会释放线程。
/// 阻塞线程,非终止状态下,调用waitone等一下的方法,这个是在同一个线程内的。线程终止
/// 终止状态下,调用waitone等一下的方法,线程不终止继续执行。
/// 三个方法:waitone(),set(),reset()
/// waitone()是阻塞这个线程
/// set()是释放被阻塞的线程
/// reset()是设置这个类是非终止状态。
/// 终止状态:应该叫可否使用状态;若是是true就是不能使用;就是终止状态;若是是false就是能使用,非终止状态。
/// 只有在非终止状态下,才能使用这个waitone才有做用。set才有做用。waitone(),set()是使其设置成终止状态,就是不阻塞状态,只有reset()才能起做用。
/// 并且在阻塞被释放时,触发是否把状态设置回非终止状态的动做。
/// 实质:这个实质应该是一个待条件的循环。若是是终止状态,调用waitone()线程不阻塞,若是是非终止状态,调用waitone()是阻塞,
///
///
///
/// 具体使用流程:
/// 调用waitone()阻塞:看是否能阻塞,能就阻塞,不能就不阻塞。再根据是否自动恢复为可以使用决定事件状态。
/// 能阻塞,调用set中止阻塞线程,并设置阻塞不可以使用。再根据是否自动恢复为可以使用决定事件状态。
/// 不能阻塞,要手动设置为非终止状态,方法是:reset().
///
///
/// 另外一线程决定此线程是否阻塞。set()是另外一线程处理的
///
///
/// 固然也能够在本线程内处理。
///
///
/// </summary>
static EventWaitHandle eHandle;测试
static void UnblockDemo()
{
Console.WriteLine("测试EventWaitHandle的初始终止状态");
eHandle = new EventWaitHandle(true, EventResetMode.AutoReset);//eHandle初始为终止状态,模式为AutoReset
eHandle.WaitOne();//因为EventWaitHandle对象eHandle初始状态为终止状态,因此这里第一次调用WaitOne时阻塞被当即释放,又因为eHandle为AutoReset模式,因此以后eHandle会被置为非终止状态
Console.WriteLine("线程未被阻塞");
eHandle.WaitOne();//因为此时eHandle已经为非终止状态,因此此时调用WaitOne线程会被阻塞
Console.WriteLine("线程被阻塞");
}spa
static void BlockDemo()
{
Console.WriteLine("测试EventWaitHandle的初始非终止状态");
eHandle = new EventWaitHandle(false, EventResetMode.AutoReset);//eHandle初始为非终止状态,模式为AutoReset
eHandle.WaitOne();//因为EventWaitHandle对象eHandle初始状态为非终止状态,因此这里第一次调用WaitOne时,线程就被组塞了;autoReset指是否被回复为非终止状态。
Console.WriteLine("线程被阻塞");
}线程
static void AutoResetDemo()
{
Console.WriteLine("测试EventWaitHandle的AutoReset模式");
eHandle = new EventWaitHandle(false, EventResetMode.AutoReset);//eHandle初始为非终止状态,模式为AutoReset
///启动另外一个线程
//ThreadPool.QueueUserWorkItem(new WaitCallback((object o) =>
//{
// //启动另外一个线程,每隔3秒钟调用一次eHandle.Set方法,为主线程释放一次阻塞,一共释放3次
// for (int i = 0; i < 3; i++)
// {
// Thread.Sleep(3000);
// eHandle.Set();//因为eHandle处于AutoReset模式,因此每次使用Set将eHandle置为终止状态后,待被WaitOne阻塞的线程被释放后,eHandle又会被自动置回非终止状态
// }
//}), null);
ThreadPool.QueueUserWorkItem(new WaitCallback(
(object o) =>
{对象
//启动另外一个线程,每隔3秒钟调用一次eHandle.Set方法,为主线程释放一次阻塞,一共释放3次
for (int i = 0; i < 3; i++)
{
Thread.Sleep(3000);
eHandle.Set();//因为eHandle处于AutoReset模式,因此每次使用Set将eHandle置为终止状态后,待被WaitOne阻塞的线程被释放后,eHandle又会被自动置回非终止状态
}事件
}同步
),null);
eHandle.WaitOne();//线程第一次被WaitOne阻塞
Console.WriteLine("第一次WaitOne调用阻塞已被释放,3秒后第二次WaitOne调用的阻塞会被释放");
eHandle.WaitOne();//线程第二次被WaitOne阻塞
Console.WriteLine("第二次WaitOne调用阻塞已被释放,3秒后第三次WaitOne调用的阻塞会被释放");
eHandle.WaitOne();//线程第三次被WaitOne阻塞
Console.WriteLine("第三次WaitOne调用阻塞已被释放,全部WaitOne调用的阻塞都已被释放");
}string
static void ManualResetDemo()
{
Console.WriteLine("测试EventWaitHandle的ManualReset模式");
eHandle = new EventWaitHandle(false, EventResetMode.ManualReset);//eHandle初始为非终止状态,模式为ManualReset
ThreadPool.QueueUserWorkItem(new WaitCallback((object o) =>
{
//启动另外一线程,3秒后调用一次eHandle.Set方法,为主线程释放WaitOne阻塞
Thread.Sleep(3000);
eHandle.Set();//因为eHandle处于ManualReset模式,因此一旦使用Set将eHandle置为终止状态后,在eHandle的Reset被调用前eHandle会一直处于终止状态,在eHandle调用Reset前,全部被WaitOne阻塞的线程会当即获得释放
}), null);it
eHandle.WaitOne();//线程第一次被WaitOne阻塞
Console.WriteLine("第一次WaitOne调用阻塞已被释放,第二次WaitOne调用的阻塞会被当即释放");
eHandle.WaitOne();//线程第二次被WaitOne阻塞
Console.WriteLine("第二次WaitOne调用阻塞已被释放,第三次WaitOne调用的阻塞会被当即释放");
eHandle.WaitOne();//线程第三次被WaitOne阻塞
Console.WriteLine("第三次WaitOne调用阻塞已被释放,全部WaitOne调用的阻塞都已被释放");io
eHandle.Reset();//调用eHandle的Reset方法,将eHandle手动置回非终止状态,以后再调用WaitOne方法就会被阻塞了
eHandle.WaitOne();//线程第四次被WaitOne阻塞
Console.WriteLine("第四次WaitOne调用阻塞已被释放");
}
static void Main(string[] args) { Console.Write("你想测试哪个方法1=UnblockDemo,2=BlockDemo,3=AutoResetDemo,4=ManualResetDemo:"); switch (Console.ReadLine()) { case "1": UnblockDemo(); break; case "2": BlockDemo(); break; case "3": AutoResetDemo(); break; case "4": ManualResetDemo(); break; default: break; } } } }