下面是一個簡單的併發節流閥和相關測試。它並不像指定的那樣更經常地觀察到併發性,但我不確定爲什麼?併發調節器
[TestFixture]
public class ConcurrencyThrottleTests
{
[Test]
public void ThrottleTest()
{
var throttle = new ConcurrencyThrottle(2);
var maxReg = new MaxRegister();
var threadPool = new SmartThreadPool();
var state = new DoWorkState {Throttle = throttle, MaxRegister = maxReg};
var workItemResults = new List<IWaitableResult>();
for (int i = 0; i < 1000; i++)
workItemResults.Add(threadPool.QueueWorkItem(DoWork, state));
SmartThreadPool.WaitAll(workItemResults.ToArray());
Assert.IsTrue(maxReg.MaxValue <= 2);
}
public void DoWork(object state)
{
var doWorkState = (DoWorkState)state;
doWorkState.Throttle.Enter();
try
{
doWorkState.MaxRegister.Increment();
Thread.Sleep(10);
}
finally
{
doWorkState.MaxRegister.Decrement();
doWorkState.Throttle.Exit();
}
}
public class DoWorkState
{
public IConcurrencyThrottle Throttle { get; set; }
public MaxRegister MaxRegister { get; set; }
}
public class ConcurrencyThrottle : IConcurrencyThrottle
{
private readonly int _max;
private readonly object _lock = new object();
private readonly MaxRegister _register = new MaxRegister();
public ConcurrencyThrottle(int max)
{
_max = max;
}
public void Exit()
{
lock (_lock)
{
_register.Decrement();
Monitor.Pulse(_lock);
}
}
public void Enter()
{
lock (_lock)
{
while (_register.CurrentValue == _max)
Monitor.Wait(_lock);
_register.Increment();
}
}
}
public class MaxRegister
{
public int MaxValue { get; private set; }
public int CurrentValue { get; private set; }
public void Increment()
{
MaxValue = Math.Max(++CurrentValue, MaxValue);
}
public void Decrement()
{
CurrentValue--;
}
}
}
首先,你的共享MaxRegister類不是線程安全的......你確定這不是問題嗎? – 2012-01-27 10:25:31
我只是從節氣門的鎖定部分調用它,所以我不認爲這是問題。 – 2012-01-27 10:28:25
但是在節流閥中你的併發性= 2,所以DoWork的try塊同時有兩個線程,對吧? (我指的是從DoWork調用MaxRegister.Increment/Decrement,而不是從ConcurrencyThrottle調用。) – 2012-01-27 10:32:10