最近,我正在研究Joe Albahari 撰写的多线程星系的精彩指南。我发现一件事我无法解释:设置取消变量后,执行最后一个循环需要很长时间(就其他部分的执行时间而言)。我尝试过 volatile 方法,也尝试过 locker 对象和 MemoryBarier 调用,结果始终相同
class Program
{
static ReaderWriterLockSlim _rw = new ReaderWriterLockSlim();
static List<int> _items = new List<int>();
static Random _rand = new Random();
static /*volatile*/ bool _cancel = false;
static object _cancelLock = new object();
static void Main()
{
Thread t1 = new Thread(Read); t1.Start();
Thread t2 = new Thread(Read); t2.Start();
Thread t3 = new Thread(Read); t3.Start();
Thread t4 = new Thread(Write); t4.Start("A");
Thread t5 = new Thread(Write); t5.Start("B");
System.Console.ReadKey();
Console.WriteLine("Cancelling... " + DateTime.Now.ToString("hh:mm:ss.ffff"));
_cancel = true;
Console.WriteLine("Cancelled " + DateTime.Now.ToString("hh:mm:ss.ffff"));
}
static void Read()
{
while (true)
{
_rw.EnterReadLock();
foreach (int i in _items) Thread.Sleep(10);
_rw.ExitReadLock();
}
}
static void Write(object threadID)
{
while (true)
{
if (_cancel)
break;
int newNumber = GetRandNum(100);
_rw.EnterWriteLock();
_items.Add(newNumber);
_rw.ExitWriteLock();
Console.WriteLine("Thread " + threadID + " added " + newNumber+" at "+DateTime.Now.ToString("hh:mm:ss.ffff"));
//Thread.Sleep(100);
}
}
static int GetRandNum(int max) { lock (_rand) return _rand.Next(max); }
}
请看输出:
Thread B added 37 at 01:52:20.2916
Thread B added 64 at 01:52:20.2916
Thread B added 89 at 01:52:20.2926
Thread B added 92 at 01:52:20.2926
Thread B added 55 at 01:52:20.2926
Thread B added 60 at 01:52:20.2926
Thread B added 0 at 01:52:20.2926
Thread A added 74 at 01:52:20.2926
Thread A added 90 at 01:52:20.2926
Thread A added 86 at 01:52:20.2926
Thread A added 91 at 01:52:20.2926
Thread A added 19 at 01:52:20.2926
Thread A added 67 at 01:52:20.2926
Thread A added 52 at 01:52:20.2926
Thread A added 73 at 01:52:20.2926
Thread A added 39 at 01:52:20.2926
Thread A added 24 at 01:52:20.2926
Thread B added 0 at 01:52:20.2926
cCancelling... 01:52:23.0229
Cancelled 01:52:23.0229
Thread A added 93 at 01:52:26.0542
Thread B added 83 at 01:52:26.0542
我期望的是,在 Canceled Line 之后没有更多内容,或者执行速度更快,例如在 1:52:23.02* 40 *
(上面的结果是当程序直接从命令提示符运行时,当从 Visual Studio 中运行时,“间隙”更小,但仍然接近 0.5 秒)。