最近在項目中碰到一個很頭疼的問題,在前端連接事件中寫了一個廣播線程,該廣播線程寫在while循環中,但是前台會有很多個客戶端,沒連接一次就會有一個廣播線程開啟,很吃資源,剛開始我解決這個問題的方法是每次觸發連接事件是檢測一下當前連接數,如果是count_client<=1,就開線程,否則跳過廣播,但這個方法只適用於連接事件中判斷,如果我是在接收事件中,根據接收結果開啟廣播線程,那麼就無法通過連接數來判斷是否該開啟廣播,我思考了好久,想起算法中有個token的概念,在此可以拿來一用。
在程序中設置一個全局線程變量tokenThread,其相當於一個令牌,擁有令牌的線程則擁有開啟線程的權限,當這個收執令牌的線程在執行的過程中,如果有其他線程想要開啟,都會被拒絕,知道當前執行線程結束,釋放令牌,其他線程才可以開啟。
因為是自己琢磨的方法,簡單的寫了個demo,如果有大牛發現demo中有不足之處 ,歡迎指出,謝謝。
demo如下:
1 static Thread tokenThread = null;//線程令牌 2 static int i = 0;//控制廣播結束 3 public static void Greating() 4 { 5 6 Thread th = new Thread(() => 7 { 8 i = 0; 9 while (i++<5)//廣播數據5次後結束 10 { 11 Console.WriteLine("我是廣播線程{0},我開始廣播啦!", Thread.CurrentThread.ManagedThreadId); 12 Thread.Sleep(1000); 13 } 14 Console.WriteLine("我不播啦!"); 15 tokenThread = null; 16 }); 17 if(tokenThread==null) //如果令牌沒人使用,則賦給該線程,否則跳過該線程 18 { 19 tokenThread = th; 20 th.Start(); 21 } 22 23 } View Code首先定義一個全程線程令牌,給其賦值為NULL,然後寫了個Greeting()函數,在函數中開了個廣播線程,廣播5次,用時5秒,廣播結束時,把令牌釋放,重新賦為NULL,在啟動線程時加了個if(tokenThread==null)的判斷,如果令牌處於釋放狀態,則當前線程獲得令牌,啟動線程,執行廣播5次,否則跳過,相當於本次Greeting()函數什麼都沒執行。
main函數很簡單,只是開了個while循環,在裡面沒1秒掉用一次Greeting()函數
1 static void Main(string[] args) 2 { 3 while (true) 4 { 5 Greating(); 6 Thread.Sleep(1000); 7 } 8 9 } View Code如果沒有令牌控制的話,沒秒都會開一個廣播線程。
最終顯示結果如下,廣播5次後會開新線程廣播: