程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 線程系列06,通過CLR代碼查看線程池及其線程,06clr

線程系列06,通過CLR代碼查看線程池及其線程,06clr

編輯:C#入門知識

線程系列06,通過CLR代碼查看線程池及其線程,06clr



在"線程系列04,傳遞數據給線程,線程命名,線程異常處理,線程池"中,我們已經知道,每個進程都有一個線程池。可以通過TPL,ThreadPool.QueueUserWorkItem,委托與線程池交互。本篇體驗:通過查看CLR代碼來觀察線程池及其線程。

□ 通過編碼查看線程池和線程

 

使用ThreadPool的靜態方法QueueUserWorkItem把線程放入線程池,來看線程池線程和主程序線程的執行情況。

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("主線程開始");
            for (int i = 0; i < 5; i++)
            {
                ThreadPool.QueueUserWorkItem(SayHello, i);
            }
            Console.WriteLine("主線程結束");
        }
        static void SayHello(object arg)
        {
            int n = (int) arg;
            Console.WriteLine("線程{0}接收到的參數是:{1},是否是後台線程:{2}",
                Thread.CurrentThread.ManagedThreadId,
                n,
                Thread.CurrentThread.IsBackground);
        }       
    }

○ 用QueueUserWorkItem方法加入線程池的線程是後台線程
○ 一旦主線程結束,後台線程隨即結束
○ 在主程序for語句塊中,有2個線程已被創建並執行

 

讓主線程和線程池線程都Sleep一段時間。

   class Program
    {
        static Random r = new Random();
        static void Main(string[] args)
        {
            Console.WriteLine("主線程開始");
            for (int i = 0; i < 5; i++)
            {
                ThreadPool.QueueUserWorkItem(SayHello, i);
            }
            Thread.Sleep(r.Next(250, 500));
            Console.WriteLine("主線程結束");
        }
        static void SayHello(object arg)
        {
            Thread.Sleep(r.Next(250, 500));
            int n = (int) arg;
            Console.WriteLine("線程{0}接收到的參數是:{1},是否是後台線程:{2}",
                Thread.CurrentThread.ManagedThreadId,
                n,
                Thread.CurrentThread.IsBackground);
        }       
    }

○ 線程池中的線程依然是後台線程
○ 讓主線程Sleep一段時間後,線程池的線程在主線程結束之前得以執行

 

再讓主線程Sleep更長的一段時間。

        static void Main(string[] args)
        {
            Console.WriteLine("主線程開始");
            for (int i = 0; i < 5; i++)
            {
                ThreadPool.QueueUserWorkItem(SayHello, i);
            }
            Thread.Sleep(r.Next(1000, 3000));
            Console.WriteLine("主線程結束");
        }

 

當主線程Sleep的時間更長後,線程池有更多的線程被執行。

 

□ 使用"即時窗口"查看CLR中的線程池和線程

 

以上,通過編碼查看線程池和線程,實在是太不方便。我們可以在"即時窗口"中,借助"SOS調試擴展"來觀察CLR中的線程池和線程。

→在"Thread.Sleep(r.Next(1000, 3000))"打上斷點
→點擊"啟動"
→當代碼運行到斷點處,點擊"調試"--"窗口"--"即時",打開"即時窗口"
→輸入如下命令,加載"SOS調試擴展"

關於"SOS調試擴展"的使用,可參考"調試查看CLR運行代碼"。
→輸入如下命令,查看線程池

○ Worker Thread顯示當前線程池中的線程狀況
○ Work Request in Queue顯示當前隊列中的線程
→輸入如下命令,查看所有線程

○ MTA (Finalizer)表示由GC回收的線程
○ MTA (Threadpool Worker) 表示線程池中的線程

 

□ 查看CLR托管堆上的所有線程類型

 

→輸入如下命令查看CLR托管堆上的所有線程類型

 

□ 查看CLR托管堆上線程池實例

 

→找到System.ThreadPoolWorkQueue,復制其前面的MT代碼
→輸入如下命令,查看線程池實例的堆地址、數量等

 

□ 查看CLR托管線程池地址

 

→復制System.Threading.ThreadPoolWorkQueue的托管堆地址
→輸入如下命令查看CLR托管線程池地址內容

 

線程系列包括:

線程系列01,前台線程,後台線程,線程同步

線程系列02,多個線程同時處理一個耗時較長的任務以節省時間

線程系列03,多線程共享數據,多線程不共享數據

線程系列04,傳遞數據給線程,線程命名,線程異常處理,線程池

線程系列05,手動結束線程

線程系列06,通過CLR代碼查看線程池及其線程

線程系列07,使用lock語句塊或Interlocked類型方法保證自增變量的數據同步


java 怎獲得線程池中正在執行的線程數?

Map map=Thread.getAllStackTraces();
System.out.println(map.size());
把這兩句話放在需要的方法裡裡,運行就可以得到結果了。
下面這句話是java api的解釋:
Thread類。
getAllStackTracespublic static Map<Thread,StackTraceElement[]> getAllStackTraces()返回所有活動線程的堆棧跟蹤的一個映射。映射鍵是線程,而每個映射值都是一個 StackTraceElement 數組,該數組表示相應 Thread 的堆棧轉儲。返回的堆棧跟蹤的格式都是針對 getStackTrace 方法指定的。
在調用該方法的同時,線程可能也在執行。每個線程的堆棧跟蹤僅代表一個快照,並且每個堆棧跟蹤都可以在不同時間獲得。如果虛擬機沒有線程的堆棧跟蹤信息,則映射值中將返回一個零長度數組。
如果有安全管理器,則通過 RuntimePermission("getStackTrace") 權限和 RuntimePermission("modifyThreadGroup") 權限調用其 checkPermission 方法,查看是否可以獲得所有線程的堆棧跟蹤。

希望以上信息對你有幫助。
 

c#怎得到線程池中某一個線程的狀態

用Thread.CurrentThreadState()這個方法獲得每個線程的信息
在函數體內寫對線程的控制。
 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved