多线程读写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个回答

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

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

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

我修改了下你的程序,在红线部分加入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]

j_clxy
clxy大叔 第8次的结果: next in Thread-4: 0 next in Thread-0: 2 next in Thread-2: 3 next in Thread-3: 1 next in Thread-1: 1 next in Thread-9: 4 next in Thread-8: 7 next in Thread-6: 6 next in Thread-5: 8 next in Thread-7: 5
大约 8 年之前 回复
j_clxy
clxy大叔 哦,code里面不支持格式。 是在第26行 Thread.sleep(1000); 这句。
大约 8 年之前 回复

俺很负责的告诉你,基本类型的都是不可变类,所以,对于基本类型的String Int 什么什么的 不用考虑多线程问题。

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐