這節我們按照線程池的核心思想來自定義一個簡單的線程池:
1) 池中使用的線程不少於一定數量,不多於一定數量
2) 池中線程不夠的時候創建,富裕的時候收回
3) 任務排隊,沒有可用線程時,任務等待
我們的目的只是實現這些“需求”,不去考慮性能(比如等待一段時間再去創建新的線程等策略)以 及特殊的處理(異常),在實現這個需求的過程中我們也回顧了線程以及線程同步的基本概念。
首先,把任務委托和任務需要的狀態數據封裝一個對象:
public class WorkItem
{
public WaitCallback Action { get; set; }
public object State { get; set; }
public WorkItem(WaitCallback action, object state)
{
this.Action = action;
this.State = state;
}
}
然後來創建一個對象作為線程池中的一個線程:
public class SimpleThreadPoolThread
{
private object locker = new object();
private AutoResetEvent are = new AutoResetEvent(false);
private WorkItem wi;
private Thread t;
private bool b = true;
private bool isWorking;
public bool IsWorking
{
get
{
lock (locker)
{
return isWorking;
}
}
}
public event Action<SimpleThreadPoolThread> WorkComplete;
public SimpleThreadPoolThread()
{
lock (locker)
{
// 當前沒有實際任務
isWorking = false;
}
t = new Thread(Work) { IsBackground = true };
t.Start();
}
public void SetWork(WorkItem wi)
{
this.wi = wi;
}
public void StartWork()
{
// 發出信號
are.Set();
}
public void StopWork()
{
// 空任務
wi = null;
// 停止線程循環
b = false;
// 發出信號結束線程
are.Set();
}
private void Work()
{
while (b)
{
// 沒任務,等待信號
are.WaitOne();
if (wi != null)
{
lock (locker)
{
// 開始
isWorking = true;
}
// 執行任務
wi.Action(wi.State);
lock (locker)
{
// 結束
isWorking = false;
}
// 結束事件
WorkComplete(this);
}
}
}