问题描述
我想实现多个线程对同一个变量进行累加,当某个线程发现这个变量超过指定值比如300,就在这个线程内部结束所有的线程运行,我写的代码如下,为什么运行的时候还是有些线程没有被结束掉呢?privateintflag=0;Thread[]threads=newThread[20];privateobjectLockThis=newSystem.Object();privatevoidbutton4_Click(objectsender,EventArgse){for(inti=0;i<threads.Length;i++){threads[i]=newThread(newParameterizedThreadStart(threadMethod));threads[i].Start(i);}}privatevoidthreadMethod(objectn){for(inti=0;i<100;i++){lock(LockThis){flag++;Console.WriteLine(flag.ToString());if(flag>=300){Console.WriteLine("线程"+n.ToString()+"检测到flag已经达到目标数值,自动终结所有线程");foreach(Threadtinthreads){t.Abort();}}}}}实际运行的时候,是这样的,总有几个线程没有被结束掉:。。。。。。295296297298299300线程2已经达到目标数值,自动终结所有线程301线程3已经达到目标数值,自动终结所有线程302线程8已经达到目标数值,自动终结所有线程上面的代码出问题在什么地方呢?除了上面的用Lock,还有什么更好的方法呢?
解决方案
解决方案二:
线程最好让它自行了断,都去判断flag就可以了.
解决方案三:
终结的过程中有新线程启动,就是说终结300的时间片间隙启动了新线程咯
解决方案四:
1、明明只操作同一个变量,你却让每个线程都对它进行同样的监视和处理,而对所有线程的Abort()又几乎是同时发生的,这一瞬间每个人都在杀掉所有人,这是一个很不周全的逻辑,可以想象你的程序当flag为300时已经混乱成什么样子,很可怕2、原则上不应在线程外结束它,这样会在线程内引发“正在终止线程”的异常,而你又没有对这些异常进行处理,所以会导致程序不会按照“看上去应该这样跑”的流程运行,举个例子:当有一个线程已经杀掉两个线程的时候,突然被别人给Abort了,这时就发生了异常,剩下的线程是不是就无法进行处理了?而同样的事情发生在每个线程中,我想这应该是关键所在。3、你在Abort()时应当先判断这个线程对象是否IsAlive,这里同样可能引发异常。多线程本来就不安全,而你通篇没有一个异常处理,这样非常不负责任。
解决方案五:
引用楼主sug254te的回复:
我想实现多个线程对同一个变量进行累加,当某个线程发现这个变量超过指定值比如300,
看到滥用线程的人我们会“绕着走”,因为一个团队开发的产品不能因为有人任性而垮掉(死掉)。如果你确实需要修改一个变量,那么修改变量之前判断一下if(abc<=300){.....修改它}
不就完了嘛。儿你满脑子的都是光怪陆离的程序幻象,没有灭定的习惯。
解决方案六:
假设就算是“玩儿”线程,在你的for循环中,在flag++语句之前,写if(flag>300)return;
很简单的流程,这就完毕了,这是基本流程,不管有多少线程你都得写这个flag<300或者flag>300的判断才算是附和最基本的业务逻辑判断。纠结Abort是多余的。连业务逻辑都没有写对,怎么可能写纯技术的代码呢?
解决方案七:
判断写在线程方法内另外详细阅读MSDN上关于Abort的解释,可以解决你的疑惑。