自定義線程池-c#的簡單實現
下面是代碼,希望大家提出更好的建議:
1.ThreadManager.cs
using System;
using System.Threading;
using System.Collections;
namespace CustomThreadPool
{
///<summary>
///線程管理器,會開啟或喚醒一個線程去執行指定的回調方法
///</summary>
public class ThreadManager
{
//線程列表,靜態
private static ArrayList threadList = new ArrayList();
//不允許創建實例
private ThreadManager()
{
}
///<summary>
///靜態方法,開啟或喚醒一個線程去執行指定的回調方法
///</summary>
///<param name="waitCallback">委托實例</param>
///<param name="obj">傳遞給回調方法的參數</param>
///<param name="timeOut">當沒有可用的線程時的等待時間,
///以毫秒為單位</param>
///<returns></returns>
public static bool QueueUserWorkItem(WaitCallback waitCallback,
Object obj, int timeOut)
{
//鎖住共享資源,實現線程安全
lock(threadList)
{
try
{
//如果線程列表為空,填充線程列表
if (threadList.Count == 0)
{
InitThreadList();
}
long startTime = DateTime.Now.Ticks;
do
{
//遍歷線程列表,找出可用的線程
foreach(MyThread myThread in threadList)
{
//線程為空,需要創建線程
if (myThread.T == null)
{
myThread.Start(waitCallback, obj, false);
return true;
}
else if (myThread.T.ThreadState ==
ThreadState.Suspended)
{//線程為掛起狀態,喚醒線程
myThread.Start(waitCallback, obj, true);
return true;
}
}
//在線程 Sleep 前釋放鎖
Monitor.PulseAll(threadList);
Thread.Sleep(500);
}
while (((DateTime.Now.Ticks -
startTime) / 10000) < timeOut);
}
finally
{
Monitor.Exit(threadList);
}
}
return false;
}
//使用 MyThread 對象填充線程列表,注意,這個時候線程並沒有啟動
private static void InitThreadList()
{
threadList = new ArrayList();
for (int i = 0; i < 10; i++)
{
MyThread t = new MyThread();
threadList.Add(t);
}
}
}
}
2.MyThread.cs
using System;
using System.Threading;
namespace CustomThreadPool
{
///<summary>
///封裝 .NET 框架提供的 Thread
///</summary>
internal class MyThread
{
//線程
private Thread t;
//委托,這里直接用 .NET 框架自帶的,
//也可以根據需要自己定義一個
private WaitCallback w;
//傳遞給符合委托的回調方法的參數值,
//根據委托的定義而定
private Object o;
///<summary>
///執行回調方法的線程
///</summary>
public Thread T
{
get
{
return t;
}
}
public MyThread()
{
}
///<summary>
///開啟新線程或喚醒線程,去執行回調方法
///</summary>
///<param name="w">用回調方法實例化了的委托實例</param>
///<param name="o">傳遞給回調方法的參數值</param>
///<param name="isSuspend">true 表示線程為掛起狀態,
///false 則表示線程還沒創建</param>
public void Start(WaitCallback w, Object o, bool isSuspend)
{
//開啟新線程或喚醒線程前,先設置
this.w = w;
this.o = o;
//線程為掛起狀態,喚醒線程繼續執行
if (isSuspend)
{
t.Resume();
}
else
{//線程還沒有創建,創建一個新線程,並執行
t = new Thread(new ThreadStart(this.ThreadProc));
t.Start();
}
}
///<summary>
///線程執行的方法
///</summary>
private void ThreadProc()
{
//死循環,使線程喚醒后不是退出,而是繼續通過委托執行回調方法
while (true)
{
//通過委托執行回調方法
w(o);
t.Suspend();
}
}
}
}
3.Test.cs
using System;
using System.Threading;
namespace CustomThreadPool
{
///<summary>
///測試自定義線程池
///</summary>
class Test
{
///<summary>
///應用程序的主入口點。
///</summary>
[STAThread]
static void Main(string[] args)
{
//
// TODO: 在此處添加代碼以啟動應用程序
//
for (int i = 0; i < 5; i++)
{
Console.WriteLine("Start thread {0}", i.ToString());
Thread t = new Thread(new ThreadStart(WorkThread));
t.Start();
}
Console.ReadLine();
Thread.CurrentThread.Abort();
}
public static void WorkThread()
{
for (int i = 0; i < 10; i++)
{
if (i % 2 == 0)
{
if (!ThreadManager.QueueUserWorkItem(
new WaitCallback(ThreadProcOne), i, 2000))
{
Console.WriteLine("Failed" + i.ToString());
}
}
else
{
if (!ThreadManager.QueueUserWorkItem(
new WaitCallback(ThreadProcTwo), i, 2000))
{
Console.WriteLine("Failed" + i.ToString());
}
}
}
Thread.CurrentThread.Abort();
}
public static void ThreadProcOne(Object stateInfo)
{
Console.WriteLine("Test custom threadpool:"
+ ((int)stateInfo).ToString());
}
public static void ThreadProcTwo(Object stateInfo)
{
Console.WriteLine("Change work:"
+ ((int)stateInfo).ToString());
}
}
}