zoukankan      html  css  js  c++  java
  • AtomicInteger类和int原生类型自增鲜明的对比

    AtomicInteger这个类的存在是为了满足在高并发的情况下,原生的整形数值自增线程不安全的问题。比如说

        int i = 0 ;
        i++;
    • 1
    • 2

    上面的写法是线程不安全的。
    有的人可能会说了,可以使用synchronized关键字啊。
    但是这里笔者要说的是,使用了synchronized去做同步的话系统的性能将会大大下降。
    所以此时AtomicInteger这个类的使用就可以满足上述的情况。
    当我们统计一个页面的浏览量的时候,可以使用该类来统计,而不再使用++运算符。

    但是在使用的过程中,笔者发现,使用++运算符和AtomicInteger的结果都是对的。。。

    结果有点晕了,难道结论是错的么?当然不是了。
    注意这个类使用的情况下是在高并发量的情况下。不是同时启10个20个线程,而是成千上万个线程。

    我们先看看AtomicInteger类起作用的代码

    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.atomic.AtomicInteger;
    
    public class AtomicIntegerTest {
        public static final AtomicInteger atomicInteger = new AtomicInteger(0);
    
        public static void main(String[] args) throws InterruptedException {
            atomicIntegerTest();
    
            Thread.sleep(3000);
            System.out.println("最终结果是" + atomicInteger.get());
        }
    
        private  static void atomicIntegerTest() {
            ExecutorService executorService = Executors.newFixedThreadPool(10000);
            for (int i = 0; i < 10000; i++) {
                executorService.execute(() -> {
                    for (int j = 0; j < 4; j++) {
                        System.out.println(atomicInteger.getAndIncrement());
                    }
                });
            }
            executorService.shutdown();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    打印的结果是4万
    这里写图片描述
    再看看++操作符

        import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class IntValueIncrementTest {
    
        public static int value = 0;
    
        public static void main(String[] args) throws InterruptedException {
            ExecutorService executorService = Executors.newFixedThreadPool(10000);
            for (int i = 0; i < 10000; i++) {
                executorService.execute(() -> {
                    for (int j = 0; j < 4; j++) {
                        System.out.println(value++);
                    }
                });
            }
            executorService.shutdown();
            Thread.sleep(3000);
            System.out.println("最终结果是" + value);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    这里写图片描述
    我们可以看到结果是39972,显然结果丢失了一些。
    所以在高并发的情况下应当使用AtomicInteger类

    当我们在并发情况下,但是并发量又不是那么大的时候,
    我们将上述的代码改掉,改为同时只有10个线程在修改数值。
    我们贴代码

    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.atomic.AtomicInteger;
    
    public class AtomicIntegerTest {
        public static final AtomicInteger atomicInteger = new AtomicInteger(0);
    
        public static void main(String[] args) throws InterruptedException {
            atomicIntegerTest();
    
            Thread.sleep(3000);
            System.out.println("最终结果是" + atomicInteger.get());
        }
    
        private  static void atomicIntegerTest() {
            ExecutorService executorService = Executors.newFixedThreadPool(10000);
            for (int i = 0; i < 10; i++) {
                executorService.execute(() -> {
                    for (int j = 0; j < 4; j++) {
                        System.out.println(atomicInteger.getAndIncrement());
                    }
                });
            }
            executorService.shutdown();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    这里写图片描述
    运行的结果是40

    再贴10个线程的并发量的情形。

    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class IntValueIncrementTest {
    
        public static int value = 0;
    
        public static void main(String[] args) throws InterruptedException {
            ExecutorService executorService = Executors.newFixedThreadPool(10000);
            for (int i = 0; i < 10; i++) {
                executorService.execute(() -> {
                    for (int j = 0; j < 4; j++) {
                        System.out.println(value++);
                    }
                });
            }
            executorService.shutdown();
            Thread.sleep(3000);
            System.out.println("最终结果是" + value);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    这里写图片描述
    发现此时的结果也是40。
    所以这就给人一种假象:
    1)AtomicInteger类不起作用.
    2)i++或者++i是线程安全的
    其实上面两点观念都是错误的。是因为并发量不够高而已
    但是需要注意的是AtomicInteger类只能保证在自增或者自减的情况下保证线程安全

    转自 https://blog.csdn.net/u013803262/article/details/72452932

  • 相关阅读:
    bzoj 1030 [JSOI2007]文本生成器
    Swift 学习笔记 (闭包)
    Swift 学习笔记 (函数)
    HTML 学习笔记 JQueryUI(Interactions,Widgets)
    HTML 学习笔记 JQuery(表单,表格 操作)
    HTML 学习笔记 JQuery(animation)
    HTML 学习笔记 JQuery(盒子操作)
    HTML 学习笔记 JQuery(事件)
    HTML 学习笔记 JQuery(DOM 操作3)
    HTML 学习笔记 JQuery(DOM 操作2)
  • 原文地址:https://www.cnblogs.com/tiancai/p/8807308.html
Copyright © 2011-2022 走看看