日期:2014-05-20  浏览次数:20650 次

Java的int类型是线程安全的?
看很多地方讲到多线程访问同一个数据,如果不进行同步会导致错误结果,但我写了一个测试却始终运行正常,请高手看看是怎么回事:
Java code

public class Main {
    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            Runnable addit = new AddOne();
            new Thread(addit).start();
        }
    }
}
public class AddOne implements Runnable {
    static int cnt = 0;
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + ",before:" + cnt);
        cnt++;
        System.out.println(Thread.currentThread().getName() + ",after:" + cnt);
    }
}


其中一次运行结果如下:
Java code

Thread-0,before:0
Thread-0,after:1
Thread-2,before:1
Thread-2,after:2
Thread-4,before:2
Thread-4,after:3
Thread-6,before:3
Thread-6,after:4
Thread-8,before:4
Thread-8,after:5
Thread-5,before:2
Thread-3,before:2
Thread-3,after:6
Thread-5,after:7
Thread-7,before:7
Thread-7,after:8
Thread-9,before:8
Thread-9,after:9
Thread-1,before:2
Thread-1,after:10


按照书上的说法,线程4和线程5拿到的初始值都是2,加1后应该都是3才对,但实际上线程5自加1后变成了7,难道int类型本身是线程安全的?

------解决方案--------------------
由于线程的不确定性,让测试线程的手段都变的不确定了

楼主这里的测试手段是:
System.out.println(Thread.currentThread().getName() + ",before:" + cnt);
cnt++;
System.out.println(Thread.currentThread().getName() + ",after:" + cnt);
这三行代码转换成字节码指令不知道成为多少行了,线程之间互相调度执行结果很难预测,所以楼主这个测试程序本身就没有什么可行性,试图从里面分析出规律是不可行的
------解决方案--------------------
我建议在 run 里写个带延时的循环,你就知道了
------解决方案--------------------
10个线程太小了,这种并发量一般不会出问题,你把线程数设为1000,10000试试