MacTalk 2017-12-09
原子类在具有逻辑的情况下输出结果也具有随机性
package com.cky.thread;
import java.util.concurrent.atomic.AtomicLong;
/**
* Created by edison on 2017/12/9.
*/
public class MyService {
public static AtomicLong ai= new AtomicLong();
public void addNum() {
System.out.println(Thread.currentThread().getName() +" 加了100之后的值是"+ ai.getAndAdd(100));
ai.getAndAdd(1);
}
}package com.cky.thread;
/**
* Created by edison on 2017/12/9.
*/
public class MyThread extends Thread{
private MyService service;
public MyThread(MyService service) {
this.service =service;
}
@Override
public void run() {
super.run();
service.addNum();
}
}package com.cky.test;
import com.cky.thread.MyService;
import com.cky.thread.MyThread;
/**
* Created by edison on 2017/12/9.
*/
public class Run {
public static void main(String[] args) {
try {
MyService myService = new MyService();
MyThread[] myThreads = new MyThread[5];
for (int i = 0; i < myThreads.length; i++) {
myThreads[i] = new MyThread(myService);
}
for (int i = 0; i < myThreads.length; i++) {
myThreads[i].start();
}
Thread.sleep(1000);
System.out.println(myService.ai.get());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}Thread-1 加了100之后的值是0 Thread-4 加了100之后的值是400 Thread-2 加了100之后的值是300 Thread-3 加了100之后的值是200 Thread-0 加了100之后的值是100 505
结果分析:
打印顺序出错了,应该每次加100在加一次1,出现这样的情况原因是addAndGet()方法是原子的,但方法和方法直接的调用却不是原子的
解决方案同步
package com.cky.thread;
import java.util.concurrent.atomic.AtomicLong;
/**
* Created by edison on 2017/12/9.
*/
public class MyService {
public static AtomicLong ai= new AtomicLong();
synchronized public void addNum() {
System.out.println(Thread.currentThread().getName() +" 加了100之后的值是"+ ai.getAndAdd(100));
ai.getAndAdd(1);
}
}Thread-1 加了100之后的值是0 Thread-3 加了100之后的值是101 Thread-4 加了100之后的值是202 Thread-0 加了100之后的值是303 Thread-2 加了100之后的值是404 505