1、计数器实现存在线程安全问题,主要由于value++非原子性操作导致
import java.util.Random;
public class Sequence {
private int value;
public int getNext(){
return value++;
}
//测试
public static void main(String[] args) {
Sequence seq = new Sequence();
//创建多个线程
for(int i = 0 ;i < 3;i++){
new Thread(new Runnable(){
@Override
public void run() {
while(true){
System.out.println(Thread.currentThread().getName() +"==="+ seq.getNext());
try {
Thread.sleep(50 * (new Random().nextInt(5)+1));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
}
}
运行结果:无法保证返回结果唯一性
Thread-0===0
Thread-2===1
Thread-1===2
Thread-2===3
Thread-1===4
Thread-2===5
Thread-0===6
Thread-2===7
Thread-0===7
Thread-0===8
Thread-1===9
Thread-1===10
Thread-2===10
Thread-0===11
Thread-0===12
2、对非原子操作使用同步synchronized,保证某一时刻只有一个线程在操作。
public synchronized int getNext(){
return value++;
}
3、使用jdk提供的原子类来解决
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;
public class Sequence {
private AtomicInteger value = new AtomicInteger(0);
public int getNext() {
return value.incrementAndGet();
}
// 测试
public static void main(String[] args) {
Sequence seq = new Sequence();
// 创建多个线程
for (int i = 0; i < 3; i++) {
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
System.out.println(Thread.currentThread().getName() + "===" + seq.getNext());
try {
Thread.sleep(50 * (new Random().nextInt(5) + 1));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
}
}