加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

JAVA中多线程的全局总和错误

发布时间:2020-12-15 02:04:26 所属栏目:Java 来源:网络整理
导读:我是 Java中多线程的新手,我做了一些代码来看看它是如何工作的.我将global = 0作为全局int变量,并使用for循环初始化大量线程(100)以将1添加到我的全局变量中.在代码的最后,结果应该是100,但不是.我有时在代码末尾99或任何其他数字(大约100).所以我的问题是,
我是 Java中多线程的新手,我做了一些代码来看看它是如何工作的.我将global = 0作为全局int变量,并使用for循环初始化大量线程(100)以将1添加到我的全局变量中.在代码的最后,结果应该是100,但不是.我有时在代码末尾99或任何其他数字(大约100).所以我的问题是,为什么线程在他们之间“打架”并且不能使总和正确?

public class test extends Thread {
    public static int global =0;
    public static void main(String[] args) throws Exception {
                for(int i=0;i<100;i++){
                String stream = String.valueOf(i);
                new test2(stream).start();
                }
                Thread.sleep(1000);
                System.out.println(global);
    }
    public test(String str) {
        super(str);
    }
    public void run() {
        int a = Integer.parseInt(getName());
        global = global+1;
        System.out.println("El hilo "+a+" tiene el número "+global);
    }
}

我知道我不需要int a = Integer.parseInt(getName());,但我假装你将来使用这个名字.并且,如果我现在删除它,结果是错误的.

解决方法

这是一个经典的比赛条件.

你的一个线程,称之为“A”,已经读取了全局值,比如10,并且向它添加了1,但它没有将值11存储回全局.

你的另一个线程,称之为“B”,现在正在读取全局的“旧”值,10,它正在向它添加1,并且它将值11存储回全局.

然后最终允许线程“A”将其值11存储回全局.已经发生了两次增量,但最终结果是只有一个增量有效地发生了.

发生这种情况是因为递增值并将其存储回变量的操作不是原子操作.这意味着有多个单独的操作,如果中断,可能会产生不正确的结果.

您必须创建一个synchronized块来强制执行原子操作.您可以锁定类对象本身.

synchronized (test.class) {
    global = global+1;
}

作为替代方案,您可以将全局变量设置为AtomicInteger,它可以为您处理原子更新.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读