刘亚贺 2012-08-06 16:35
浏览 384
已采纳

多线程读写int值不需要同步?

很多地方讲多线程时使用了下面UnsafeSequence类的getNext方法,说明如果不同步会得到错误的结果,但我的测试却从未出现过错误,请高手看看是怎么回事,谢谢!
多个线程同时持有对象us,它的getNext方法没有进行同步,按照书上的说法,由于有几个线程会同时拿到value,然后加1,10个线程分别加1后最终应该是一个小于9的值,但测试结果总是9。
[code="java"]
public class Main2 {
public static void main(String[] args) {
UnsafeSequence us = new UnsafeSequence();
for (int i = 0; i < 10; i++) {
Runnable myRunnable = new MyRunnable(us);
new Thread(myRunnable).start();
}
}
}
public class MyRunnable implements Runnable {
private final UnsafeSequence us;
public MyRunnable(UnsafeSequence _us) {
us = _us;
}
@Override
public void run() {
System.out.println("next in " + Thread.currentThread().getName() + ": "
+ +us.getNext());
}
}
public class UnsafeSequence {
public int value = 0;

public int getNext() {
    return value++;
}

}[/code]
下面是运行结果:

next in Thread-0: 0
next in Thread-9: 5
next in Thread-7: 4
next in Thread-5: 3
next in Thread-3: 2
next in Thread-1: 1
next in Thread-2: 6
next in Thread-4: 7
next in Thread-6: 8
next in Thread-8: 9

  • 写回答

2条回答 默认 最新

  • clxy大叔 2012-08-06 17:26
    关注

    多线程同步问题就是这点让人头疼:不是每次必然发生,有时候依赖数据或运行环境。

    你的测试中没有发生的原因可能有很多,比如:

    • 机器是单核的话,基本不会发生。多核的更加容易发生。
    • 机器是多核的,但测试程序没能被系统分配成多线程。
    • 运气问题。

    我修改了下你的程序,在红线部分加入1秒睡眠,在我的环境下,是第3次发生的。

    [code="java"]

    public class Test2 {
    public static void main(String[] args) {

        UnsafeSequence us = new UnsafeSequence();
        int count = 10;
    
        Thread[] ts = new Thread[count];
        for (int i = 0; i < count; i++) {
            Thread t = new Thread(new MyRunnable(us));
            ts[i] = t;
            t.start();
        }
    }
    

    }

    class MyRunnable implements Runnable {
    private final UnsafeSequence us;

    public MyRunnable(UnsafeSequence _us) {
        us = _us;
    }
    
    @Override
    public void run() {
        try {
            [color=red]Thread.sleep(1000);[/color]
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("next in " + Thread.currentThread().getName() + ": "
                + +us.getNext());
    }
    

    }

    class UnsafeSequence {
    public int value = 0;

    public int getNext() {
        return value++;
    }
    

    }
    [/code]

    出错的结果如下

    [code="java"]

    next in Thread-1: 0
    next in Thread-0: 0
    next in Thread-2: 1
    next in Thread-5: 2
    next in Thread-3: 3
    next in Thread-4: 4
    next in Thread-7: 5
    next in Thread-8: 6
    next in Thread-6: 7
    next in Thread-9: 8
    [/code]

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 微信公众号自制会员卡没有收款渠道啊
  • ¥15 stable diffusion
  • ¥100 Jenkins自动化部署—悬赏100元
  • ¥15 关于#python#的问题:求帮写python代码
  • ¥20 MATLAB画图图形出现上下震荡的线条
  • ¥15 关于#windows#的问题:怎么用WIN 11系统的电脑 克隆WIN NT3.51-4.0系统的硬盘
  • ¥15 perl MISA分析p3_in脚本出错
  • ¥15 k8s部署jupyterlab,jupyterlab保存不了文件
  • ¥15 ubuntu虚拟机打包apk错误
  • ¥199 rust编程架构设计的方案 有偿