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; } 作为替代方案,您可以将全局变量设置为 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |