i++是线程安全的吗

不是!!(经典的内存不可见问题) 因为每个线程都有自己的工作内存,每个线程需要对共享变量操作的时候必须先把共享变量从主内存load到自己的工作内存,登完成对共享变量的操作时再保存到主内存。如果一个线程运算完成后还没刷到主内存,此时这个共享变量的值被另一个线程从主内存读取到了,这个时候读取的数据就是脏数据了,他会覆盖其他线曾程计算的值。

注意:

使用volatile 让内存可见也无法解决此问题,因为vilatile只能保证可见性,不能保证原子性。多个线程同事读取这个共享变量的值,就算保证其他线程修改的可见性,也不能保证线程之间读取到同样的值,然后相互覆盖对方的值的情况。

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;

public class i_security_view {
    static int count = 0;
    //static AtomicInteger count = 0;   解决方案二
    static CountDownLatch cdl = new CountDownLatch(10);

    public static void main(String[] args) throws Exception {
        CountRunnable countRunnable = new CountRunnable();
        for (int i = 0; i < 10; i++) {
            new Thread(countRunnable).start();
        }
        cdl.await();
        System.out.println(count);
    }

    static class CountRunnable implements Runnable {
        private  void  count() {
            for (int i = 0; i < 1000; i++) {
               //synchronized (CountRunnable.class){ //      解决方案一
                    count++;
              //  }
            }
        }
        @Override
        public void run() {
            count();
            cdl.countDown();
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_33583322/article/details/80910261
i++