黑马程序员技术交流社区
标题: 来个大神解释下,关于这个多线程的问题 [打印本页]
作者: vtming 时间: 2014-3-15 17:56
标题: 来个大神解释下,关于这个多线程的问题
package com.test1;
public classDthread {
public static void main(String[] args) {
// TODO Auto-generated method stub
Test1t1 = newTest1();
Threadth0 = newThread(t1);
Threadth1 = newThread(t1);
th0.start();
th1.start();
}
}
class Test1 implements Runnable{
private int a=0;
@Override
public void run() {
// TODO Auto-generated method stub
//下面代码有线程安全问题
a = a + 1;
System.out.println(Thread.currentThread().getName()+ "A="+ a);
// for(inti=0;i<20;i++){
// a= a + 1;
// System.out.println(Thread.currentThread().getName()+ "A=" + a);
// }
}
}
程序输出的几种结果:
(1)
Thread-0A=1//这种结果10次出现一次,运气好100次出现一次
Thread-1A=1//此结果很奇怪,不应该出现这种问题。需要多次运行才会出现
(2)
Thread-0A=1
Thread-1A=2
(3)
Thread-0A=2
Thread-1A=2
(4)
Thread-0A=2
Thread-1A=1
第(1)种结果很匪夷所思,有线程安全问题,也不应该出现这种数据。两个线程都会执行一次加法,数据是共享的,应该至少有一个线程输出A=2.似乎少计算了一次.
用注释中的for循环输出也会出现这种问题,但只会在开始时都输出A=1,最后结果也只会少计算一次。
我猜测a=a+1这一步是同时进行的,两线程运算时拿到的a都等于0,重复了一次a=0+1.又或者是双核CPU的原因???
我想知道这种问题到底是怎么出现的?
截图:
作者: 王浩龙 时间: 2014-3-15 18:09
我看了一下你的代码,我的解释如下你可以参考一下啊。
当线程Thread-0执行到a = a + 1;这段代码时候停止这时候可以知道a=0,然后Thread-1也开始执行,它进来的时候肯定a还是等于0,所以最后输出的结果有可能是都等于1.
作者: 目标 时间: 2014-3-15 18:29
本帖最后由 目标 于 2014-3-15 18:33 编辑
我觉得可能是和多核处理器有关,a = a + 1; 这条语句可能被多核同时执行了,就是CPU1执行th0,CPU2执行th1,而且是同时开始同时结束的。个人认为,等待高手来解答
作者: vtming 时间: 2014-3-15 20:39
有木有高手!!!求高手解答。。。
作者: 杯之水 时间: 2014-3-17 11:18
- class ClassThread {
- public static void main(String[] args) {
- Test1 t1 = new Test1();
- Thread th0 = new Thread(t1);
- Thread th1 = new Thread(t1);
-
- th0.start();
- th1.start();
- }
- }
- class Test1 implements Runnable{
- private int a=0;
- public void run() {
- while(true){
- synchronized(this){
- a = a + 1;
- System.out.println(Thread.currentThread().getName()+ "A="+ a);
- }
- }
- }
- }
复制代码
在执行a=a+1前面加上锁synchronized(this){}就可以避免两个线程同时取1的情况,当其中一个线程执行完毕,a的值改变后,另一个线程开始执行a=a+1操作。
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) |
黑马程序员IT技术论坛 X3.2 |