public class App {
public static void main(String[] args) throws Exception {
AtomicInteger atomicInteger = new AtomicInteger(0);
Map<Integer, AtomicInteger> map = new HashMap();
map.put(1, atomicInteger);
AtomicBoolean ok1 = new AtomicBoolean(false);
AtomicBoolean ok2 = new AtomicBoolean(false);
Object lock = new Object();
new Thread(() -> {
for (int i = 0; i < 1000; i++) {
AtomicInteger atomicInteger1;
synchronized (lock){
System.out.println(Thread.currentThread().getName() + map.get(1).get());
atomicInteger1 = new AtomicInteger(map.get(1).incrementAndGet());
}
map.put(1,atomicInteger1 );
}
ok1.set(true);
},"线程1:").start();
new Thread(() -> {
for (int i = 0; i < 1000; i++) {
AtomicInteger atomicInteger1;
synchronized (lock){
System.out.println(Thread.currentThread().getName() + map.get(1).get());
atomicInteger1 = new AtomicInteger(map.get(1).incrementAndGet());
}
map.put(1,atomicInteger1 );
}
ok2.set(true);
},"线程2:").start();
while(!ok1.get() && !ok2.get()){
}
System.out.println("最终结果===============:" + map.get(1).get());
}
}
AtomicInteger保证自增不会出现线程安全问题的前提下,synchronized保证了拿到的数就立马输出,即只有抢到锁的线程有机会顺序输出当前拿到的数据。
只测试hashMap的 put 和 get的线程安全性
期望结果输出为2000
数据结果不正确 所以线程不安全
在线程1 通过get拿到1085后 执行打印 put 再次进入循环执行get后,拿到的值还是1085,上一个循环中put方法传入的1086还没有更新到hashMap的槽位当中,已经被get出来,导致了get线程安全问题,若在1086循环的put方法执行之后,1085循环中的put方法才执行完毕,则1086数值丢失,自增总数不及预期数值。