C#多线程相关知识
例 运行如下函数,任意输入起始顺序如ABC、BAC、CAB,修改Problem类,使最终输出结果为ABC
//不可修改该部分代码
static void Main(string[] args)
{
Console.WriteLine("请输入起始顺序:例如(ABC,BAC,CAB)");
List<char> InitStr = Console.ReadLine().ToList();
Problem problem = new Problem();
InitStr.ForEach(e => {
if (e == 'A')
{
Task.Run(() => {
problem.A(() => Console.Write("A"));
});
}
if (e == 'B')
{
Task.Run(() => {
problem.B(() => Console.Write("B"));
});
}
if (e == 'C')
{
Task.Run(() => {
problem.C(() => Console.Write("C"));
});
}
});
Console.ReadKey();
}
//修改该部分代码完成功能
public class Problem
{
public Problem() { }
public void A(Action printA)
{
// 输出A方法,不可修改删除该方法
printA();
}
public void B(Action printB)
{
// 输出B方法,不可修改删除该方法
printB();
}
public void C(Action printC)
{
// 输出C方法,不可修改删除该方法
printC();
}
}
1.设置标志位,While+Thread.Sleep(1)方式实现
using System.Threading;
public class Problem
{
int Fleg = 1;
public Problem()
{
}
public void A(Action printA)
{
// 输出A方法,不可修改删除该方法
printA();
Fleg = 2;
}
public void B(Action printB)
{
while (Fleg != 2) { Thread.Sleep(1); }
// 输出B方法,不可修改删除该方法
printB();
Fleg = 3;
}
public void C(Action printC)
{
while (Fleg != 3) { Thread.Sleep(1); }
// 输出B方法,不可修改删除该方法
printC();
}
}
1.设置标志位
2.执行完A函数后将标志位更改为满足B函数执行的条件,相同道理C函数也一样
3.函数判断标志位,若不满足则等待.这里需要Sleep(1),释放CPU时间片
2.通过自动信号量AutoResetEvent方式实现
using System.Threading;
public class Problem
{
private AutoResetEvent _b = new AutoResetEvent(false);
private AutoResetEvent _c = new AutoResetEvent(false);
public Problem()
{
}
public void A(Action printA)
{
// 输出A方法,不可修改删除该方法
printA();
_b.Set();
}
public void B(Action printB)
{
_b.WaitOne();
// 输出B方法,不可修改删除该方法
printB();
_c.Set();
}
public void C(Action printC)
{
_c.WaitOne();
// 输出C方法,不可修改删除该方法
printC();
}
}
3.通过自旋锁SpinWait方式实现
using System.Threading;
public class Problem
{
private SpinWait _spinWait = new SpinWait();
private int _fleg = 1;
public Problem()
{
}
public void A(Action printA)
{
// 输出A方法,不可修改删除该方法
printA();
Thread.VolatileWrite(ref _fleg,2);
}
public void B(Action printB)
{
while (Thread.VolatileRead(ref _fleg) != 2)
{
_spinWait.SpinOnce();
}
// 输出B方法,不可修改删除该方法
printB();
Thread.VolatileWrite(ref _fleg,3);
}
public void C(Action printC)
{
while (Thread.VolatileRead(ref _fleg) != 3)
{
_spinWait.SpinOnce();
}
// 输出C方法,不可修改删除该方法
printC();
}
}
4.通过信号量SemaphoreSlim方式实现
using System.Threading;
public class Problem
{
private SemaphoreSlim SemaphoreSlimB = new SemaphoreSlim(0,1);
private SemaphoreSlim SemaphoreSlimC = new SemaphoreSlim(0,1);
public Problem()
{
}
public void A(Action printA)
{
// 输出A方法,不可修改删除该方法
printA();
SemaphoreSlimB.Release();
}
public void B(Action printB)
{
SemaphoreSlimB.Wait();
// 输出B方法,不可修改删除该方法
printB();
SemaphoreSlimC.Release();
}
public void C(Action printC)
{
SemaphoreSlimC.Wait();
// 输出C方法,不可修改删除该方法
printC();
}
}
5.通过同步计数CountdownEvent方式实现
using System.Threading;
public class Problem
{
CountdownEvent countdownEventB = new CountdownEvent(1);
CountdownEvent countdownEventC = new CountdownEvent(1);
public Problem()
{
}
public void A(Action printA)
{
// 输出A方法,不可修改删除该方法
printA();
countdownEventB.Signal();
}
public void B(Action printB)
{
countdownEventB.Wait();
// 输出B方法,不可修改删除该方法
printB();
countdownEventC.Signal();
}
public void C(Action printC)
{
countdownEventC.Wait();
// 输出C方法,不可修改删除该方法
printC();
}
}