刘亚贺 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 程序不包含适用于入口点的静态Main方法
  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记