Я использую приведенный ниже код для реализации и тестирования очереди блокировки. Я тестирую очередь, запустив 5 параллельных потоков (удалителей), чтобы вытащить элементы из очереди, блокируя, если очередь пуста и 1 параллельный поток (сумматор), чтобы добавить элементы в очередь. Однако, если я оставлю его достаточно долго, я получаю исключение, потому что один из потоков удаления выходит из состояния ожидания, даже когда очередь пуста.
Кто-нибудь знает, почему я получаю исключение? Заметьте, мне интересно узнать, почему это не работает в отличие от рабочего решения (как я могу просто Google это).
Я очень благодарен за вашу помощь.
using System;
using System.Threading;
using System.Collections.Generic;
namespace Code
{
class Queue<T>
{
private List<T> q = new List<T>();
public void Add(T item)
{
lock (q)
{
q.Add(item);
if (q.Count == 1)
{
Monitor.Pulse(q);
}
}
}
public T Remove()
{
lock (q)
{
if (q.Count == 0)
{
Monitor.Wait(q);
}
T item = q[q.Count - 1];
q.RemoveAt(q.Count - 1);
return item;
}
}
}
class Program
{
static Random r = new Random();
static Queue<int> q = new Queue<int>();
static int count = 1;
static void Adder()
{
while (true)
{
Thread.Sleep(1000 * ((r.Next() % 5) + 1));
Console.WriteLine("Will try to add");
q.Add(count++);
}
}
static void Remover()
{
while (true)
{
Thread.Sleep(1000 * ((r.Next() % 5) + 1));
Console.WriteLine("Will try to remove");
int item = q.Remove();
Console.WriteLine("Removed " + item);
}
}
static void Main(string[] args)
{
Console.WriteLine("Test");
for (int i = 0; i < 5; i++)
{
Thread remover = new Thread(Remover);
remover.Start();
}
Thread adder = new Thread(Adder);
adder.Start();
}
}
}