线程同步的其他方式:
1、AutoResetEvent
使用WaitOne和set 进行阻塞和释放阻塞的线程,
WaitOne方法定义:
public virtual bool WaitOne(int millisecondsTimeout);该方法用来阻塞线程,当在指定的时间间隔还没有收到一个信号时,将返回false。
public AutoResetEvent(bool initialState); 当initialState值为false时线程阻塞等待set信号或者等待超时时间结束,当为true时不进行线程阻塞。
millisecondsTimeout 为超时时间 当设置的超时时间到时 无论是否收到了set的信号 线程将解除阻塞的状态立即执行 WaitOne的返回值为false 当收到set的信号解除线程阻塞时返回值为true。
例子:
using System;
using System.Threading;
namespace KenelMode
{
class Program
{
// 初始化自动重置事件,并把状态设置为非终止状态
// 如果这里把初始状态设置为True时,
// 当调用WaitOne方法时就不会阻塞线程,看到的输出结果的时间就是一样的了
// 因为设置为True时,表示此时已经为终止状态了。
public static AutoResetEvent autoEvent = new AutoResetEvent(false);
static void Main(string[] args)
{
Console.WriteLine("Main Thread Start run at: " +DateTime.Now.ToLongTimeString());
Thread t = new Thread(TestMethod);
t.Start();
// 阻塞主线程1秒后
// 调用 Set方法释放线程,使线程t可以运行
Thread.Sleep(3000);
// Set 方法就是把事件状态设置为终止状态。
autoEvent.Set();
Console.Read();
}
public static void TestMethod()
{
if (autoEvent.WaitOne(2000))
{
Console.WriteLine("Get Singal to Work");
// 3秒后线程可以运行,所以此时显示的时间应该和主线程显示的时间相差一秒
Console.WriteLine("Method Restart run at: " + DateTime.Now.ToLongTimeString());
}
else
{
Console.WriteLine("Time Out to work");
Console.WriteLine("Method Restart run at: " + DateTime.Now.ToLongTimeString());
}
}
}
}
2、信号量(Semaphore)
信号量(Semaphore)是由内核对象维护的int变量,当信号量为0时,在信号量上等待的线程会堵塞,信号量大于0时,就解除堵塞。当在一个信号量上等待的线程解除堵塞时,内核自动会将信号量的计数减1。在.net 下通过Semaphore类来实现信号量同步。
Semaphore类限制可同时访问某一资源或资源池的线程数。线程通过调用 WaitOne方法将信号量减1,并通过调用 Release方法把信号量加1
class Program
{
// 初始信号量计数为0,最大计数为10
public static Semaphore semaphore =new Semaphore(0,10);
public static int time = 0;
static void Main(string[] args)
{
for (int i = 0; i < 5; i++)
{
Thread test = new Thread(new ParameterizedThreadStart(TestMethod));
// 开始线程,并传递参数
test.Start(i);
}
// 等待1秒让所有线程开始并阻塞在信号量上
Thread.Sleep(500);
// 信号量计数加4
// 最后可以看到输出结果次数为4次
semaphore.Release(4);
Console.Read();
}
public static void TestMethod(object number)
{
// 设置一个时间间隔让输出有顺序
int span = Interlocked.Add(ref time, 100);
Thread.Sleep(1000 + span);
//信号量计数减1
semaphore.WaitOne();
Console.WriteLine("Thread {0} run ", number);
}
}
3、 Mutex 使用Mutex.WaitOne()和Mutex.ReleaseMutex();