C#线程同步
2021-01-03 01:28
标签:wirte wait ace 状态 场景 err class highlight count 原子操作类: Mutex类: SemaphoreSlim: AutoResetEvent: ManualResetEventSlim: CountdownEvent: Barrier: ReaderWriterLockSlim C#线程同步 标签:wirte wait ace 状态 场景 err class highlight count 原文地址:https://www.cnblogs.com/sunliyuan/p/12992581.html public abstract class CounterBase
{
public abstract void Increase();
public abstract void Decrease();
}
public class CounterNoInterlocked : CounterBase
{
public int Count { get; private set; }
public override void Decrease()
{
Count--;
}
public override void Increase()
{
Count++;
}
}
public class CounterWithInterlocked : CounterBase
{
private int _count;
public int Count { get { return _count; } }
public override void Decrease()
{
Interlocked.Decrement(ref _count);
}
public override void Increase()
{
Interlocked.Increment(ref _count);
}
}
static void Main(string[] args)
{
// 应用场景:WinForm应用程序只能启动一个
string mutexName = "互斥量";
using (var mutex = new Mutex(false, mutexName))
{
if (mutex.WaitOne(TimeSpan.FromSeconds(5), false))
{
Console.WriteLine("运行中....");
Console.ReadLine();
mutex.ReleaseMutex();
}
else
{
Console.WriteLine("第二个程序运行啦。。。。");
}
}
Console.WriteLine("Hello World!");
}
static SemaphoreSlim _semaphoreSlim = new SemaphoreSlim(10);
///
//false:无信号,子线程的WaitOne方法不会被自动调用;
//true:有信号,子线程的WaitOne方法会被自动调用。
// 只有一个线程可以看到信号的改变
static AutoResetEvent _resetEvent = new AutoResetEvent(false);
static int number = -1;
public static void Start()
{
Thread t = new Thread(ReadThreadProc);
t.Name = "Read";
t.Start();
for (int i = 0; i
class Sample2
{
public static void Start()
{
RemoteRequest request = new RemoteRequest();
new Thread(request.RequestInterfaceA).Start();
new Thread(request.RequestInterfaceB).Start();
AutoResetEvent.WaitAll(request._resetEvents.ToArray());
request.RequestInterfaceC();
}
}
class RemoteRequest
{
public IList _resetEvents;
public RemoteRequest()
{
_resetEvents = new List();
_resetEvents.Add(new AutoResetEvent(false));
_resetEvents.Add(new AutoResetEvent(false));
}
public void RequestInterfaceA()
{
Console.WriteLine("异步调用远程接口A获取用户数据...");
Thread.Sleep(TimeSpan.FromSeconds(2));
_resetEvents[0].Set();
Console.WriteLine("接口A数据获取完成!");
}
public void RequestInterfaceB()
{
Console.WriteLine("异步调用远程接口B获取订单数据...");
Thread.Sleep(TimeSpan.FromSeconds(1));
_resetEvents[1].Set();
Console.WriteLine("接口B订单数据获取完成!");
}
public void RequestInterfaceC()
{
Console.WriteLine("接口A和接口B的数据获取完成,开始处理C接口数据...");
}
}
static ManualResetEventSlim _event = new ManualResetEventSlim(false);
static void Main(string[] args)
{
var t1 = new Thread(() => { ThroughGates(5); });
var t2 = new Thread(() => { ThroughGates(6); });
var t3 = new Thread(() => { ThroughGates(12); });
t1.Name = "t1";
t2.Name = "t2";
t3.Name = "t3";
t1.Start();
t2.Start();
t3.Start();
Console.WriteLine("主线程暂停6秒");
Thread.Sleep(TimeSpan.FromSeconds(6));
Console.WriteLine("主线程打开传送门...");
_event.Set();
Console.WriteLine("主线程暂停2秒");
Thread.Sleep(TimeSpan.FromSeconds(2));
Console.WriteLine("主线程关闭传送门...");
_event.Reset();
Console.WriteLine("主线程暂停10秒");
Thread.Sleep(TimeSpan.FromSeconds(10));
Console.WriteLine("主线程第二次打开传送门...");
_event.Set();
Console.WriteLine("主线程暂停2秒");
Thread.Sleep(TimeSpan.FromSeconds(2));
Console.WriteLine("主线程第二次关闭传送门...");
_event.Reset();
Console.ReadKey();
}
static void ThroughGates(int seconds)
{
Console.WriteLine($"线程{Thread.CurrentThread.Name}进入传送门之前先暂停{seconds}秒。");
//for (int i = 1; i
static CountdownEvent _event = new CountdownEvent(3);
static void Test(int seconds)
{
Console.WriteLine($"{Thread.CurrentThread.Name}线程开始执行...");
Thread.Sleep(TimeSpan.FromSeconds(seconds));
Console.WriteLine($"{Thread.CurrentThread.Name}线程执行完成!") ;
_event.Signal();
}
static void Main(string[] args)
{
Thread t1 = new Thread(() => { Test(2); });
t1.Name = "t1";
Thread t2 = new Thread(() => { Test(4); });
t2.Name = "t2";
Thread t3 = new Thread(() => { Test(6); });
t3.Name = "t3";
t1.Start();
t2.Start();
t3.Start();
_event.Wait();
Console.WriteLine("所有的线程执行完毕!");
_event.Dispose();
Console.ReadKey();
}
// 当您需要一组任务并行地运行一连串的阶段,
// 但是每一个阶段都要等待所有其他任务都完成前一阶段之后才能开始,
// 你可以通过Barrier实例来同步这一类协同工作
static Barrier _barrier = new Barrier(3, b => {
Console.WriteLine($"=========当前是{b.CurrentPhaseNumber+1}阶段===============");
});
static void Test(string step1, string step2, string step3, int seconds)
{
string threadName = Thread.CurrentThread.Name;
Console.WriteLine($"线程{threadName}开始执行第一阶段操作:{step1}");
Thread.Sleep(TimeSpan.FromSeconds(seconds));
_barrier.SignalAndWait();
Console.WriteLine($"线程{threadName}开始执行第二阶段操作:{step2}");
Thread.Sleep(TimeSpan.FromSeconds(seconds));
_barrier.SignalAndWait();
Console.WriteLine($"线程{threadName}开始执行第三阶段操作:{step3}");
Thread.Sleep(TimeSpan.FromSeconds(seconds));
_barrier.SignalAndWait();
Console.WriteLine($"线程{threadName}所有操作执行完毕");
}
static void Main(string[] args)
{
Thread t1 = new Thread(() => { Test("步兵列阵", "步兵冲锋", "步兵退守", 3); });
t1.Name = "t1";
Thread t2 = new Thread(() => { Test("骑兵列阵", "骑兵冲锋", "骑兵退守", 4); });
t2.Name = "t2";
Thread t3 = new Thread(() => { Test("炮兵列阵", "炮兵装弹", "炮兵开炮", 5); });
t3.Name = "t3";
t1.Start();
t2.Start();
t3.Start();
Console.ReadKey();
}
class Program
{
static void Main(string[] args)
{
new Thread(Read) { IsBackground = true }.Start();
new Thread(Read) { IsBackground = true }.Start();
new Thread(Read) { IsBackground = true }.Start();
new Thread(() => Write("线程 1"))
{
IsBackground = true
}.Start();
new Thread(() => Write("线程 2"))
{
IsBackground = true
}.Start();
Thread.Sleep(TimeSpan.FromSeconds(30));
Console.ReadKey();
}
//读写锁的概念很简单,允许多个线程同时获取读锁,但同一时间只允许一个线程获得写锁,因此也称作共享-独占锁。
//在C#中,推荐使用ReaderWriterLockSlim类来完成读写锁的功能。
//某些场合下,对一个对象的读取次数远远大于修改次数,如果只是简单的用lock方式加锁,则会影响读取的效率。
//而如果采用读写锁,则多个线程可以同时读取该对象,只有等到对象被写入锁占用的时候,才会阻塞。
private static ReaderWriterLockSlim _rw = new ReaderWriterLockSlim();
private static Dictionary
上一篇:自定义springboot - starter 实现日志打印
下一篇:C#线程基础