一、线程不安全例子
计数
cs
const int total = 100_000;
int count = 0;
var thread1 = new Thread(Increment);
var thread2 = new Thread(Increment);
thread1.Start();
thread2.Start();
thread1.Join();
thread2.Join();
Console.WriteLine($"Count: {count}");
void Increment()
{
for (int i = 0; i < total; i++)
count++;
}
操作队列
cs
var queue = new Queue<int>();
var producer = new Thread(Producer);
var consumer1 = new Thread(Consumer);
var consumer2 = new Thread(Consumer);
producer.Start();
consumer1.Start();
consumer2.Start();
producer.Join();
Thread.Sleep(100); // Wait for consumers to finish
consumer1.Interrupt();
consumer2.Interrupt();
consumer1.Join();
consumer2.Join();
void Producer()
{
for (int i = 0; i < 20; i++)
{
Thread.Sleep(20);
queue.Enqueue(i);
}
}
void Consumer()
{
try
{
while (true)
{
if (queue.TryDequeue(out var res))
Console.WriteLine(res);
Thread.Sleep(1);
}
}
catch (ThreadInterruptedException)
{
Console.WriteLine("Thread interrupted.");
}
}
二、Parallel与PLINQ
cs
var inputs = Enumerable.Range(1,20).ToArray();
int HeavyJob(int input)
{
Thread.Sleep(300);
return input;
}
// Sequential
var forOutputs = new int[inputs.Length];
for (int i = 0; i < inputs.Length; i++)
{
forOutputs[i] = HeavyJob(inputs[i]);
}
// Parallel
var parallelOutputs = new int[inputs.Length];
Parallel.For(0, inputs.Length, i =>
{
parallelOutputs[i] = HeavyJob(inputs[i]);
});
// PLINQ
var plinqOutputs = inputs.AsParallel().Select(HeavyJob).ToArray();
三、PLINQ 与信号量
cs
using System.Diagnostics;
var inputs = Enumerable.Range(1,20).ToArray();
var semaphore = new Semaphore(3, 3);
int HeavyJob(int input)
{
semaphore.WaitOne();
Thread.Sleep(300);
semaphore.Release();
return input;
}
var sw = Stopwatch.StartNew();
var plinqOutputs = inputs.AsParallel().Select(HeavyJob).ToArray();
sw.Stop();
Console.WriteLine($"Elapsed time: {sw.ElapsedMilliseconds}ms");
四、线程终止
cs
//线程终止
var thread = new Thread(() =>
{
try
{
for (int i = 0; i < 10; i++)
{
Thread.Sleep(1000);
Console.WriteLine("Sub thread: " + i);
}
}
catch (ThreadInterruptedException)
{
Console.WriteLine("Thread interrupted");
}
});
thread.Start();
Thread.Sleep(3500);
thread.Interrupt();
thread.Join();
Console.WriteLine("Done");