zoukankan      html  css  js  c++  java
  • AtomicBoolean使用

    AtomicBoolean是java.util.concurrent.atomic的原子变量的类;可以看到下面还有很多类似的Atomic这样的类,如下图所示

    这样的类具有原子性,在多线程的环境下使用是线程安全的;举个例子,在多线程环境中,我们通过判断一个boolan变量的值,然后修改该变量的值,之后进行操作;

    存在一个问题就是,多个线程可能都读到该变量的值是符合条件的,然后都去修改了变量的值;其实只需要一个线程执行就可以了,主要的原因就是因为if判断和set值是两个操作,

    这里面存在线程安全的问题;Atomic类型的变量就不存在这种问题;

    下面通过一个例子来说明;

    1>使用基本的boolean类型

    public class BarWorker implements Runnable {
     
        private String name;
     
        private static boolean exists = false;
     
        public BarWorker(String name) {
            this.name = name;
        }
     
        @Override
        public void run() {
            if (!exists) {
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                exists = true;
                System.out.println(name + ":enter");
                try {
                    TimeUnit.SECONDS.sleep(2);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(name + ":leave");
                exists = false;
            } else {
                System.out.println(name + ":give up");
            }
        }
     
        public static void main(String[] args) {
            BarWorker bar1 = new BarWorker("bar1");
            BarWorker bar2 = new BarWorker("bar2");
            new Thread(bar1).start();
            new Thread(bar2).start();
     
        }
    }
    

      上面为了模拟if判断和赋值操作的原子性,故意在之间设置了个时间间隔;执行结果

    bar1:enter
    bar2:enter
    bar1:leave
    bar2:leave
    从执行结果可以看出,两个线程都执行了对应的操作;
    

      2>使用AtomicBoolean

    public class AtomaticTest implements Runnable {
     
        private String name;
     
        private static AtomicBoolean exists = new AtomicBoolean(false);
     
        public AtomaticTest(String name) {
            this.name = name;
        }
     
        @Override
        public void run() {
            if(exists.compareAndSet(false, true)) {
                System.out.println(name + ":enter");
                try {
                    TimeUnit.SECONDS.sleep(2);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(name + ":leave");
                exists.set(false);
            }else{
                System.out.println(name +":give up");
            }
        }
     
        public static void main(String[] args) {
            AtomaticTest atomatic1 = new AtomaticTest("bar1");
            AtomaticTest atomatic2 = new AtomaticTest("bar2");
            new Thread(atomatic1).start();
            new Thread(atomatic2).start();
        }
    }
    

      

    bar2:enter
    bar1:give up
    bar2:leave
    

      

    可见只执行了一个线程;这里使用了compareAndSet。

    这个方法主要两个作用

    1. 比较AtomicBoolean和expect的值,如果一致,执行方法内的语句。其实就是一个if语句

    2. 把AtomicBoolean的值设成update,比较最要的是这两件事是一气呵成的,这连个动作之间不会被打断,任何内部或者外部的语句都不可能在两个动作之间运行


  • 相关阅读:
    C# 文件类的操作---删除
    C#实现Zip压缩解压实例
    UVALIVE 2431 Binary Stirling Numbers
    UVA 10570 meeting with aliens
    UVA 306 Cipher
    UVA 10994 Simple Addition
    UVA 696 How Many Knights
    UVA 10205 Stack 'em Up
    UVA 11125 Arrange Some Marbles
    UVA 10912 Simple Minded Hashing
  • 原文地址:https://www.cnblogs.com/felixzh/p/11887684.html
Copyright © 2011-2022 走看看