关于多个线程操作同一变量遇到问题,求指教

问题描述

我想实现多个线程对同一个变量进行累加,当某个线程发现这个变量超过指定值比如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的解释,可以解决你的疑惑。

时间: 2024-07-31 11:52:05

关于多个线程操作同一变量遇到问题,求指教的相关文章

java多线程操作同一个变量的问题,难道是多核cpu所致?

问题描述 java多线程操作同一个变量的问题,难道是多核cpu所致? 大家请看代码和输出结果,我百思不得其解,为什么 amount只加了一次,开始我以为是static所致,就算去掉也还是有几率出现这样的结果,难道是多核cpu真的把两个线程同时执行了? package study; public class MyRunnable implements Runnable { public static int amount=0; @Override public void run() { // TO

java读取操作系统环境变量

变量 java读取操作系统环境变量 /**文件名:SysProb.java描述: 取得当前系统变量的程序. java中的System.getProperty只是针对JVM来的,如果要取得系统环境变量,还要用到系统相关的函数作者: 慈勤强Email :cqq1978@Gmail.com**/ import java.util.*;import java.io.*; class SysProb{ //返回当前系统变量的函数,结果放在一个Properties里边,这里只针对win2k以上的,其它系统可

C#中跨线程操作控件

一.前面的话 对于一些耗时型操作(如文件下载),让主线程去处理不是明智的选择,虽然这样做会使得程序开发起来很简单.因为WinForm程序设计的 准则之一就是Responsive,即让用户觉得程序一直在工作,而不是感觉它在罢工(呵呵,事实上,程序不会罢工,只是你没给他表现得机会, 如果它有情感,会觉得委屈死)..Net FrameWork支持在程序用应用线程编程,这可以很好的解决上述问题,不过有时候直接使用Thread和 Threadstart显得有些繁琐也没必要,为此.Net Framework

Android线程操作对象AsyncTask线程机制

 简单的说,一个程序只有一个主线程,可以有多个主线程.在Android世界中也是这样,Android属于单线程模型,耗时操作必须放在非主线程中执行,故而谷歌为了方便我们使用线程,为我们提供一个AsyncTask多线程操作对象.   对于Android使用线程还有一点需要特别注意,哪就是Android不允许在子线程中更新UI,相信很多初学者一定遇到过这个问题,这个怎么解决呢?在Activity中,我们可以通过   new Thread(new Runnable() { @Override publ

ios-block里为什么不能操作成员变量?

问题描述 block里为什么不能操作成员变量? 我想在一个block里对一个成员变量赋值,但是提示" use of undeclared identifier self"错误, 请问这是怎么回事? 代码如下: void (^successBlock)(id ) = ^(id responseObject){ NSLog(@"responseObject:%@",responseObject); NSInteger result = [[responseObject

4.QT中进程操作,线程操作

 QT中的线程操作 T19Process.pro SOURCES += \     main.cpp   CONFIG += C++11 main.cpp #include <QCoreApplication> #include <QProcess> #include <QDebug> int main(int argc, char** argv) {     QCoreApplication app(argc, argv);       QProcess proc

ui-关于android子线程操作UI的问题

问题描述 关于android子线程操作UI的问题 看到的所有的资料上都说android的子线程不能操作UI,抱着好奇心我写了下面的程序,竟然运行成功了,不知谁能解释一下这个问题 public class MainActivity extends Activity { Button bt; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setCon

MFC什么情况需要锁定线程里的变量?

问题描述 MFC什么情况需要锁定线程里的变量? MFC什么情况需要锁定线程里的变量?为什么锁定了变量计算结果还是不稳定?感觉和计算顺序有关系,谁能详细解释下? 解决方案 什么叫结果不稳定,贴出你的程序和结果出来看下.

NSIS操作系统环境变量

原文:NSIS操作系统环境变量 手头有个项目需要修改PATH变量 需要!include "EnvVarUpdate.nsh"   以下是NSIS脚本代码 ; Script generated by the HM NIS Edit Script Wizard. !include "StrFunc.nsh" ; HM NIS Edit Wizard helper defines !define PRODUCT_NAME "Setup_Wintech"