zoukankan      html  css  js  c++  java
  • Java并发包:AtomicBoolean和AtomicReference

     

    AtomicBoolean

    AtomicBoolean是一个读和写都是原子性的boolean类型的变量。这里包含高级的原子操作,例如compareAndSet()。AtomicBoolean位于Java.util.concurrent.atomic包中,因此全类名是java.util.concurrent.atomic.AtomicBoolean。这篇文章讲述的AtomicBoolean的版本可以在java 8中找到,第一个版本在java 5中增加。

    AtomicBoolean设计背后的原理在我的另一篇文章Compare and Swap有解释。

    创建AtomicBoolean

    你可以像下面一样创建一个AtomicBoolean:

    AtomicBoolean atomicBoolean = new AtomicBoolean();
    • 1

    这个例子创建了一个AtomicBoolean默认值为false。

    如果你需要显示的设置AtomicBoolean的初始值,你可以给AtomicBoolean传递一个初始值。

    AtomicBoolean atomicBoolean = new AtomicBoolean(true);
    • 1
    • 获取AtomicBoolean的值

    你可以使用get()方法获取AtomicBoolean的值,下面是一个例子:

    AtomicBoolean atomicBoolean = new AtomicBoolean(true);
    
    boolean value = atomicBoolean.get();
    • 1
    • 2
    • 3

    执行上面的代码后value变量的值将为ture。

    • 设置AtomicBoolean的值

    你可以使用set()方法设置AtomicBoolean的值,下面是一个例子:

    AtomicBoolean atomicBoolean = new AtomicBoolean(true);
    
    atomicBoolean.set(false);
    • 1
    • 2
    • 3

    执行上面的代码后atomicBoolean 变量的值将为false。

    • 交换AtomicBoolean的值。

    你可以使用getAndSet()交换AtomicBoolean的值。getAndSet()方法返回AtomicBoolean当前的值,并给它设置一个新的值。下面是一个例子:

    AtomicBoolean atomicBoolean = new AtomicBoolean(true);
    
    boolean oldValue = atomicBoolean.getAndSet(false);
    • 1
    • 2
    • 3

    执行上面的代码后oldValue的值为true,AtomicBoolean实例的值为false.代码有效的交换了当前值为true的AtomicBoolean值使之为false。

    • 比较和设置AtomicBoolean的值

    compareAndSet()可以使AtomicBoolean的当前值和你期望的值作对比。如果当前值就是你期望的值,一个新的值会在AtomicBoolean上设置。compareAndSet()方法是原子的,因此,同一时刻仅允许一个线程执行它。于是,compareAndSet()方法可以用于实现简单的同步器例如锁。

    下面是使用compareAndSet()的例子:

    AtomicBoolean atomicBoolean = new AtomicBoolean(true);
    
    boolean expectedValue = true;
    boolean newValue      = false;
    
    boolean wasNewValueSet = atomicBoolean.compareAndSet(
        expectedValue, newValue);
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    这个例子中把AtomicBoolean的当前值和true做对比,如果两个值相等,将会给AtomicBoolean设置一个新值false。

    AtomicReference

    AtomicReference类提供了一种读和写都是原子性的对象引用变量。原子意味着多个线程试图改变同一个AtomicReference(例如比较和交换操作)将不会使得AtomicReference处于不一致的状态。AtomicReferenc的compareAndSet()方法可以使得它与期望的一个值进行比较,如果他们是相等的,AtomicReference里的对象会被设置成一个新的引用。

    创建AtomicReference

    你可以下面这样创建一个AtomicReference的实例。

    AtomicReference atomicReference = new AtomicReference();
    • 1

    如果你需要使用一个初始引用来创建AtomicReference,你可以像下面这样做。

    String initialReference = "the initially referenced string";
    AtomicReference atomicReference = new AtomicReference(initialReference);
    • 1
    • 2
    • 创建泛型AtomicReference

    你可以使用java泛型创建一个类型化的AtomicReference。下面是一个例子:

    AtomicReference<String> atomicStringReference =
        new AtomicReference<String>();
    • 1
    • 2

    你也可以给类型化的AtomicReference指定初始值,下面是给类型化的AtomicReference指定初始值的例子:

    String initialReference = "the initially referenced string";
    AtomicReference<String> atomicStringReference =
        new AtomicReference<String>(initialReference);
    • 1
    • 2
    • 3

    获得AtomicReference引用

    你可以使用AtomicReference的get()方法获的存储在AtomicReference中的引用。如果你在非泛型化的AtomicReference上使用get()方法将会返回一个Object引用。如果在泛型化的AtomicReference上使用get()方法将会返回你在AtomicReference上声明的类型的引用。

    下面是一个非泛型化的AtomicReference的get()的例子:

    AtomicReference atomicReference = new AtomicReference("first value referenced");
    
    String reference = (String) atomicReference.get();
    • 1
    • 2
    • 3

    注意,当AtomicReference是一个非泛型化的时,必须将get()方法返回的引用强制转换为String,因为get()放好的是一个Object引用。

    下面是一个泛型化的AtomicReference的例子:

    AtomicReference<String> atomicReference = 
         new AtomicReference<String>("first value referenced");
    
    String reference = atomicReference.get();
    • 1
    • 2
    • 3
    • 4

    注意,这里不需要将get()返回的引用进行强制转换,因为编译器知道它返回一个String引用。

    设置AtomicReference引用

    你可以使用set()方法设置储存在AtomicReferenc实例中的引用。对于非泛型化的AtomicReference的实例,set()方法会将一个Object引用作为参数。对于泛型化的AtomicReference,set()方法将使用你在AtmoicReference上声明的类型的引用作为参数。

    下面是一个AtomicReference的set()的例子:

    AtomicReference atomicReference = 
         new AtomicReference();
    
    atomicReference.set("New object referenced");
    • 1
    • 2
    • 3
    • 4

    对于泛型和非泛型的引用在使用set()上看起并没有什么不同。唯一的不同是编译器会对泛型的AtomicReference有类型约束。

    比较和设置AtomicReference引用

    AtomicReference有一个非常有用的方法是compareAndSet()。compareAndSet()方法可以将存储在AtomicReference中的引用同你的预期值做一个比较,如果他们是相同的(not equal as in equals() but same as in ==),那么在AtomicReference实例上会设置一个新的引用。

    如果compareAndSet()方法给AtomicReference设置了新的引用,它会返回true。否则会返回false。

    下面是AtomicReference compareAndSet()方法的例子:

    String initialReference = "initial value referenced";
    
    AtomicReference<String> atomicStringReference =
        new AtomicReference<String>(initialReference);
    
    String newReference = "new value referenced";
    boolean exchanged = atomicStringReference.compareAndSet(initialReference, newReference);
    System.out.println("exchanged: " + exchanged);
    
    exchanged = atomicStringReference.compareAndSet(initialReference, newReference);
    System.out.println("exchanged: " + exchanged);
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    上面的例子中使用了一个初始的引用创建了一个泛型化的AtomicReference。然后调用两次compareAndSet()方法来比较储存的引用和初始的引用。如果储存的引用与初始引用是相等的将会设置一个新的引用。第一次的时候两个引用是相等的,因此AtomicReference被设置了一个新的引用。第二次储存的引用是之前调用compareAndSet()放新设置的引用,因此储存的引用一定是与初始的引用是不相等的。于是,AtomicReference不会被设置成一个新的引用,compareAndSet()方法返回false。

  • 相关阅读:
    引用kernel32.dll中的API来进行串口通讯
    vs2017 项目生成时不产生xml文件的方法
    session的处理机制
    用户未登录或Session超时时重定向到登录页,不那么简单
    VS C# debug文件夹中各文件的作用
    Tomcat(免安装版)的安装与配置【转】
    关于C#关闭窗体后,依旧有后台进程在运行的解决方法
    DatakeyNames和datakey
    ASP.NET页面生命周期描述
    比较C#中几种常见的复制字节数组方法的效率
  • 原文地址:https://www.cnblogs.com/zyy1688/p/10654709.html
Copyright © 2011-2022 走看看