线程令牌
最近在项目中碰到一个很头疼的问题,在前端连接事件中写了一个广播线程,该广播线程写在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 }
首先定义一个全程线程令牌,给其赋值为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 }
如果没有令牌控制的话,没秒都会开一个广播线程。
最终显示结果如下,广播5次后会开新线程广播: