前篇回顧:上篇講了資料庫連接配接池的問題,其實關于是否是活動連接配接還是有很大問題可以挖掘的。這個有空蟲子再和大家交流了
本篇談下線程池的相關問題,希望各位看官留個爪印,應用程式池和資料庫連接配接池可能大部分程式員不需要關心那個,不過線程池可所謂是重頭戲了。
先把蟲子的觀點放上: 個人表示排斥在項目中使用ThreadPool這個類,至于.net中關聯到ThreadPool的資源我們暫且不做讨論。如果需要操作線程池可以使用第三方例如SmartThreadPool或者自己按照自己的項目需求開發一個。
線程池的相關概念我就不多說了,同樣這裡我隻介紹下。線程池中容易被忽視的問題。
一. 相對池外線程,池内線程操作的性能極差!
<a href="http://blog.51cto.com/dubing/712451#">?</a>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<code>ManualResetEvent[] MR = </code><code>new</code> <code>ManualResetEvent[10];</code>
<code> </code><code>for</code> <code>(</code><code>int</code> <code>i = 0; i < 10; i++)</code>
<code> </code><code>{</code>
<code> </code><code>MR[i] = </code><code>new</code> <code>ManualResetEvent(</code><code>false</code><code>);</code>
<code> </code><code>}</code>
<code> </code><code>int</code> <code>a, b;</code>
<code> </code><code>ThreadPool.GetMaxThreads(</code><code>out</code> <code>a, </code><code>out</code> <code>b);</code>
<code> </code><code>Console.WriteLine(</code><code>string</code><code>.Format(</code><code>"(輔助線程的最大數目{0} I/O線程的最大數目{1}) 初始狀态"</code><code>, a, b));</code>
<code> </code><code>ThreadPool.GetAvailableThreads(</code><code>out</code> <code>a, </code><code>out</code> <code>b);</code>
<code> </code><code>Console.WriteLine(</code><code>string</code><code>.Format(</code><code>"(可用輔助線程的最大數目{0} 可用I/O線程的最大數目{1}) 初始狀态"</code><code>, a, b));</code>
<code> </code>
<code> </code><code>Stopwatch sw = Stopwatch.StartNew();</code>
<code> </code>
<code> </code><code>new</code> <code>Thread((qq) =></code>
<code> </code><code>{</code>
<code> </code><code>Console.WriteLine(</code><code>"這是個線程池外的線程"</code><code>+qq.ToString());</code>
<code> </code><code>MR[(</code><code>int</code><code>)qq].Set();</code>
<code> </code><code>Thread.Sleep(5000);</code>
<code> </code><code>}) { }.Start(i);</code>
<code> </code><code>WaitHandle.WaitAll(MR);</code>
<code> </code><code>Console.WriteLine(</code><code>"生成池外10個線程 共耗時"</code> <code>+ sw.ElapsedMilliseconds);</code>
<code> </code><code>foreach</code> <code>(ManualResetEvent me </code><code>in</code> <code>MR)</code>
<code> </code><code>me.Reset();</code>
<code> </code><code>Thread.Sleep(500);</code>
<code> </code><code>Console.WriteLine(</code><code>string</code><code>.Format(</code><code>"(可用輔助線程的最大數目{0} 可用I/O線程的最大數目{1}) 線程池外啟動線程後"</code><code>, a, b));</code>
<code> </code><code>sw = Stopwatch.StartNew();</code>
<code> </code><code>ThreadPool.QueueUserWorkItem(qq =></code>
<code> </code><code>{ </code>
<code> </code><code>Console.WriteLine(</code><code>"這是個線程池内的線程"</code> <code>+ qq.ToString());</code>
<code> </code><code>Thread.Sleep(20000);</code>
<code> </code>
<code> </code><code>},i);</code>
<code> </code><code>Console.WriteLine(</code><code>"生成池内10個線程 共耗時"</code> <code>+ sw.ElapsedMilliseconds);</code>
<code> </code><code>Thread.Sleep(6000);</code>
<code> </code><code>Console.WriteLine(</code><code>string</code><code>.Format(</code><code>"(可用輔助線程的最大數目{0} 可用I/O線程的最大數目{1}) 線程池内啟動線程後"</code><code>, a, b));</code>
在初始狀态後 生成線程的效率存在百倍的差距!!!不過線程池既然是池的作用那麼在程式運作中應該會好很多。
二。線程池内的線程隻能是背景線程。
三。不能為線程設定優先級。在高精度的項目中線程池不适用。
四。所支援的Callback不能有傳回值。WaitCallback隻能帶一個object類型的參數,沒有任何傳回值。
五。容易被幹擾,同時容易破壞項目的應用環境。舉些例子
<code>static</code> <code>void</code> <code>Main(</code><code>string</code><code>[] args)</code>
<code> </code><code>{ </code>
<code> </code><code>//哪些函數會影響線程池</code>
<code> </code><code>int</code> <code>a, b;</code>
<code> </code><code>Timer timer = </code><code>new</code> <code>Timer((qq) =></code>
<code> </code><code>{ </code>
<code> </code><code>Console.WriteLine(</code><code>"這是一個timer"</code><code>);</code>
<code> </code><code>Thread.Sleep(2000);</code>
<code> </code><code>}, </code><code>null</code><code>, 2000, 1000);</code>
<code> </code>
<code> </code><code>ThreadPool.GetAvailableThreads(</code><code>out</code> <code>a, </code><code>out</code> <code>b);</code>
<code> </code><code>Console.WriteLine(</code><code>string</code><code>.Format(</code><code>"(可用輔助線程的最大數目{0} 可用I/O線程的最大數目{1}) Timer啟動後"</code><code>, a, b));</code>
<code> </code><code>timer.Dispose();</code>
<code> </code><code>timer = </code><code>new</code> <code>Timer((qq) =></code>
<code> </code><code>{ </code>
<code> </code><code>ThreadPool.GetAvailableThreads(</code><code>out</code> <code>a, </code><code>out</code> <code>b);</code>
<code> </code><code>Console.WriteLine(</code><code>string</code><code>.Format(</code><code>"(可用輔助線程的最大數目{0}/可用I/O線程的最大數目{1}) Timer資源占用ing"</code><code>, a, b));</code>
<code> </code><code>var</code> <code>act = </code><code>new</code> <code>Action(testmethod);</code>
<code> </code><code>var</code> <code>qqt = act.BeginInvoke(CallbackMethod, act);</code>
<code> </code><code>Console.ReadLine();</code>
<code> </code><code>}</code>
<code> </code><code>static</code> <code>void</code> <code>CallbackMethod(IAsyncResult ar)</code>
<code> </code><code>{</code>
<code> </code><code>var</code> <code>caller = (Action)ar.AsyncState;</code>
<code> </code><code>caller.EndInvoke(ar);</code>
<code> </code><code>Console.WriteLine(</code><code>"Action回調結束"</code><code>);</code>
<code> </code>
<code> </code><code>static</code> <code>void</code> <code>testmethod()</code>
<code> </code><code>Console.WriteLine(</code><code>"Action開始"</code><code>);</code>
<code> </code><code>Console.WriteLine(</code><code>string</code><code>.Format(</code><code>"(可用輔助線程的最大數目{0} 可用I/O線程的最大數目{1}) Action啟動ing"</code><code>, a, b));</code>
<code> </code><code>Thread.Sleep(2000);</code>
<code> </code>
至于還有哪些,大家可以各自讨論,或者提出反對的意見。
本文轉自 熬夜的蟲子 51CTO部落格,原文連結:http://blog.51cto.com/dubing/712451