C#线程间同步的几种实现方式
2016-03-01 20:30
633 查看
一、使用信号量
using System;using System.Threading;
namespace SemaphoreDemo
{
class Program
{
static void Main(string[] args)
{
for(int i = 0; i <= 6; i++)
{
string threadName = "thread " + i;
int secondsToWait = 2 + 2 * i;
var t = new Thread(() => AccessDatabase(threadName, secondsToWait));
t.Start();
}
Console.ReadKey();
}
//可同时有四个资源可访问
static SemaphoreSlim _semaphore = new SemaphoreSlim(4);
static void AccessDatabase(string name, int seconds)
{
Console.WriteLine("{0} waits to access a database", name);
_semaphore.Wait();
Console.WriteLine("{0} was granted an access to a database", name);
Thread.Sleep(TimeSpan.FromSeconds(seconds));
Console.WriteLine("{0} is completed", name);
_semaphore.Release();
}
}
}
二、使用AutoResetEvent
using System;using System.Threading;
namespace AutoResetEventDemo
{
class Program
{
static void Main(string[] args)
{
var t = new Thread(() => Process(10));
t.Start();
Console.WriteLine("waiting for another thread to complete work");
_workerEvent.WaitOne();
Console.WriteLine("first operation is completed!");
Console.WriteLine("performing an operation on a main thread");
Thread.Sleep(TimeSpan.FromSeconds(5));
_mainEvent.Set();
Console.WriteLine("now running the second operation on a second thread");
_workerEvent.WaitOne();
Console.WriteLine("second operation is completed!");
Console.ReadKey();
}
private static AutoResetEvent _workerEvent = new AutoResetEvent(false);
private static AutoResetEvent _mainEvent = new AutoResetEvent(false);
static void Process(int seconds)
{
Console.WriteLine("starting a long running work...");
Thread.Sleep(TimeSpan.FromSeconds(seconds));
Console.WriteLine("work is done!");
_workerEvent.Set();
Console.WriteLine("waiting for a main thread to complete its work");
_mainEvent.WaitOne();
Console.WriteLine("starting second operation...");
Thread.Sleep(TimeSpan.FromSeconds(seconds));
Console.WriteLine("work is done!");
_workerEvent.Set();
}
}
}
三、使用ManualResetEvent
using System;using System.Threading;
namespace ManualResetEventSlimDemo
{
class Program
{
static void Main(string[] args)
{
var t1 = new Thread(() => TravelThroughGates("thread 1", 5));
var t2 = new Thread(() => TravelThroughGates("thread 2", 5));
var t3 = new Thread(() => TravelThroughGates("thread 3", 5));
t1.Start();
t2.Start();
t3.Start();
Thread.Sleep(TimeSpan.FromSeconds(6));
Console.WriteLine("the gates are now open!");
_mainEvent.Set();
Thread.Sleep(TimeSpan.FromSeconds(2));
_mainEvent.Reset();
Console.WriteLine("the gates have been closed!");
Thread.Sleep(TimeSpan.FromSeconds(10));
Console.WriteLine("the gates are now open for the second time!");
_mainEvent.Set();
Thread.Sleep(TimeSpan.FromSeconds(2));
Console.WriteLine("the gate have been closed!");
_mainEvent.Reset();
Console.ReadKey();
}
static ManualResetEventSlim _mainEvent = new ManualResetEventSlim(false);
static void TravelThroughGates(string threadName, int seconds)
{
Console.WriteLine("{0} fails to sleep", threadName);
Thread.Sleep(TimeSpan.FromSeconds(seconds));
Console.WriteLine("{0} waits for the gates to open!", threadName);
_mainEvent.Wait();
Console.WriteLine("{0} enters the gates!", threadName);
}
}
}
四、使用CountDownEvent
using System;using System.Threading;
namespace CountDownEventDemo
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("starting two operations");
var t1 = new Thread(() => PerformOperation("operation 1 is completed", 4));
var t2 = new Thread(() => PerformOperation("operation 2 is completed", 8));
t1.Start();
t2.Start();
//等待所有信号量返回
//如果没有Signal()返回,将永久性等待;或可使用带时间参数方式等待
_countdown.Wait();
Console.WriteLine("both operation have been completed");
_countdown.Dispose();
Console.ReadKey();
}
//计数为2
static CountdownEvent _countdown = new CountdownEvent(2);
static void PerformOperation(string message, int seconds)
{
Thread.Sleep(TimeSpan.FromSeconds(seconds));
Console.WriteLine(message);
//返回信号
_countdown.Signal();
}
}
}
相关文章推荐
- C#百万数据查询超时问题
- C#解决界面不响应
- C#调用SendMessage 用法
- C#开机自动启动程序代码
- C#操作文件
- C#复合控件获取值,及事件一处理顺顺序
- C#读取txt文件
- C# 操作XML
- C#毫秒转时分秒格式
- C# 反射笔记
- C#发送POST,GET,DELETE请求API,并接受返回值
- 【笔记】《C#大学教程》- 第3章 C#编程介绍
- C#中字符串前面加@的作用
- c#子线程执行完怎么通知主线程
- c#开发的程序安装时动态指定windows服务名称
- C# 自动生成mac地址软件
- C#数据类型安全转换
- C# Lambda表达式、匿名、回调
- C#中base和this关键字
- C#中override和overload的区别