以下に例を示します。両方のコヒーレントアルゴリズムが同じオブジェクトを使用して全体的にロックされている間に、なぜキューがロックされているのかわかりません。この例のキューロックが必要な理由
キューロックが必要であると言われています。
using System;
using System.Threading;
using System.Collections;
public class CrudeThreadPool
{
static readonly int MaxWorkThreads = 4;
static readonly int WaitTimeout = 2000;
public delegate void WorkDelegate();
public CrudeThreadPool() {
stop = false;
workLock = new Object();
workQueue = new Queue();
threads = new Thread[ MaxWorkThreads ];
for(int i = 0; i < MaxWorkThreads; ++i) {
threads[i] =
new Thread(new ThreadStart(this.ThreadFunc));
threads[i].Start();
}
}
private void ThreadFunc() {
lock(workLock) {
do {
if(!stop) {
WorkDelegate workItem = null;
if(Monitor.Wait(workLock, WaitTimeout)) {
lock(workQueue.SyncRoot) {
workItem =
(WorkDelegate) workQueue.Dequeue();
}
workItem();
}
}
} while(!stop);
}
}
public void SubmitWorkItem(WorkDelegate item) {
lock(workLock) {
lock(workQueue.SyncRoot) {
workQueue.Enqueue(item);
}
Monitor.Pulse(workLock);
}
}
public void Shutdown() {
stop = true;
}
private Queue workQueue;
private Object workLock;
private Thread[] threads;
private volatile bool stop;
}
public class EntryPoint
{
static void WorkFunction() {
Console.WriteLine("WorkFunction() called on Thread {0}",
Thread.CurrentThread.ManagedThreadId);
}
static void Main() {
CrudeThreadPool pool = new CrudeThreadPool();
for(int i = 0; i < 10; ++i) {
pool.SubmitWorkItem(
new CrudeThreadPool.WorkDelegate(
EntryPoint.WorkFunction));
}
Thread.Sleep(1000);
pool.Shutdown();
}
}
キューをロックする理由はなんですか?
あなたはどこでそのコードを取得しましたか、それはなぜ動作すると思われますか? – Evk
そのコードは間違いなく機能します。それは1つのコースブックから来ます。 –
このコードを複数回実際に実行しようとすると、コードが壊れていることがわかります。あなたは10個のアイテムをキューに入れますが、ランダムな数のアイテムが処理されます。ときどき10、ときには8、時には4、ときには0になります。それを書いた人は自分が何をしているのか理解できませんでした(特にMonitor.PulseとMonitor.Waitの動作)。なぜキューアクセスをロックするのかについて議論する理由はあまりありません。 – Evk