先上例子,赋值i=5,然后i--,用5个线程跑
MyThread.java
package sys_out_print_i;
public class MyThread extends Thread{
private int i = 5;
@Override
public void run(){
System.out.println("i="+(i--)+" threadName="+Thread.currentThread().getName());
}
}
Run.java
package sys_out_print_i;
public class Run {
public static void main(String[] args) {
// TODO Auto-generated method stub
MyThread m = new MyThread();
Thread t1 = new Thread(m);
Thread t2 = new Thread(m);
Thread t3 = new Thread(m);
Thread t4 = new Thread(m);
Thread t5 = new Thread(m);
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
}
}
结果:
i=5 threadName=Thread-1
i=3 threadName=Thread-3
i=4 threadName=Thread-2
i=1 threadName=Thread-4
i=2 threadName=Thread-5
虽然println()方法在内部是同步的,但是i--的操作却在进入println()之前发生的,所以出现非线程安全。
用synchronized就可以解决。
PS:我不知道其中的原理是什么,路过的大神可以指教,--i测试过没有问题,所以我觉得是JVM的处理方式造成的。
i--在JVM中的操作步骤分三步:
1)取得i原有值
2)计算i-1
3)对i进行赋值