これらの要件を持つ単純なデータ構造が必要です。
- キューのように動作する必要があります。
- すべてのエンキュー操作はアトミックである必要があります。
マルチスレッドの経験は非常に限られていますが、これが私が思いついたものです:
public class Tickets
{
private ConcurrentQueue<uint> _tickets;
public Tickets(uint from, uint to)
{
Initialize(from, to);
}
private readonly object _lock = new object();
public void Initialize(uint from, uint to)
{
lock(_lock)
{
_tickets = new ConcurrentQueue<uint>();
for (uint i = from; i <= to; i++)
{
_tickets.Enqueue(i);
}
}
}
public uint Dequeue()
{
uint number;
if (_tickets.TryDequeue(out number))
{
return number;
}
throw new ArgumentException("Ticket queue empty!");
}
}
最初の質問: このコードは大丈夫ですか?
2 番目の質問: このクラスを単体テストするにはどうすればよいですか (たとえば、要素 (1、2、3、4、5、6) を持つキューで定期的にデキュー操作を実行している 2 つのスレッドで、最初のスレッドは奇数のみを取得し、 2 番目のスレッドは偶数のみ)? 私はこれを試しましたが、アサートは実行されていません:
[Test]
public void Test()
{
var tickets = new Tickets(1, 4);
var t1 = new Thread(() =>
{
Assert.AreEqual(1, tickets.Dequeue());
Thread.Sleep(100);
Assert.AreEqual(3, tickets.Dequeue());
});
var t2 = new Thread(() =>
{
Assert.AreEqual(2, tickets.Dequeue());
Thread.Sleep(100);
Assert.AreEqual(4, tickets.Dequeue());
});
t1.Start();
t2.Start();
}