原子類在具有有邏輯性的情況下輸出結(jié)果也具有隨機(jī)性
/**
* @author wuyoushan
* @date 2017/4/19.
*/
public class MyService {
public static AtomicLong atomicLong=new AtomicLong();
public void addNum(){
System.out.println(Thread.currentThread().getName()+"加了100之后的值是:"
+atomicLong.addAndGet(100));
atomicLong.addAndGet(1);
}
}
/**
* MyThread線程測(cè)試
* @author wuyoushan
* @date 2017/3/21.
*/
public class MyThread extends Thread {
private MyService myService;
public MyThread(MyService myService) {
super();
this.myService = myService;
}
@Override
public void run() {
super.run();
myService.addNum();
}
}
/**
* @author wuyoushan
* @date 2017/3/20.
*/
public class Run {
public static void main(String[] args){
try{
MyService service=new MyService();
MyThread[] array=new MyThread[5];
for (int i = 0; i < array.length; i++) {
array[i]=new MyThread(service);
}
for (int i = 0; i < array.length; i++) {
array[i].start();
}
Thread.sleep(1000);
System.out.println(service.atomicLong.get());
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
程序的運(yùn)行結(jié)果為:
Thread-2加了100之后的值是:100
Thread-3加了100之后的值是:201
Thread-4加了100之后的值是:502
Thread-0加了100之后的值是:401
Thread-1加了100之后的值是:301
505
打印順序出錯(cuò)了,應(yīng)該是每加1次100再加1次1.出現(xiàn)這樣的情況是因?yàn)閍ddAndGet()方法是原子的,但方法和方法之間的調(diào)用卻不是原子的。解決這樣的問題必須要同步。
更改MyService.java文件代碼如下:
/**
* @author wuyoushan
* @date 2017/4/19.
*/
public class MyService {
public static AtomicLong atomicLong=new AtomicLong();
synchronized public void addNum(){
System.out.println(Thread.currentThread().getName()+"加了100之后的值是:"
+atomicLong.addAndGet(100));
atomicLong.addAndGet(1);
}
}
程序的運(yùn)行結(jié)果為:
Thread-0加了100之后的值是:100
Thread-1加了100之后的值是:201
Thread-2加了100之后的值是:302
Thread-3加了100之后的值是:403
Thread-4加了100之后的值是:504
505
從運(yùn)行的結(jié)果可以看到,是每次加100再加1,這就是我們想要得到的過程,結(jié)果505的同時(shí)還保證在過程中的累加的順序也是正確的。
摘選自 java多線程核心編程技術(shù)-2.3.6