欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java AtomicInteger類使用方法實(shí)例講解

 更新時(shí)間:2020年06月17日 10:45:14   作者:King-D  
這篇文章主要介紹了Java AtomicInteger類使用方法實(shí)例講解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

1、java.util.concurrent.atomic 的包里有AtomicBoolean, AtomicInteger,AtomicLong,AtomicLongArray,
AtomicReference等原子類的類,主要用于在高并發(fā)環(huán)境下的高效程序處理,來(lái)幫助我們簡(jiǎn)化同步處理.

在Java語(yǔ)言中,++i和i++操作并不是線程安全的,在使用的時(shí)候,不可避免的會(huì)用到synchronized關(guān)鍵字。而AtomicInteger則通過(guò)一種線程安全的加減操作接口。

2、AtomicInteger的基本方法

創(chuàng)建一個(gè)AtomicInteger

System.out.println(atomicInteger.get());

--->輸出 : 123

創(chuàng)建一個(gè)不傳值的,默認(rèn)值為0

AtomicInteger atomicInteger = new AtomicInteger();
System.out.println(atomicInteger.get());
---->輸出: 0

獲取和賦值

atomicInteger.get(); //獲取當(dāng)前值
atomicInteger.set(999); //設(shè)置當(dāng)前值

atomicInteger.compareAndSet(expectedValue,newValue)

public static void main(String[] args) {
    AtomicInteger atomicInteger = new AtomicInteger(0);
    System.out.println(atomicInteger.get());

    int expectedValue = 123;
    int newValue   = 234;
    Boolean b =atomicInteger.compareAndSet(expectedValue, newValue);
    System.out.println(b);
    System.out.println(atomicInteger);

  }

----》輸出結(jié)果為: 0 false 0


 public static void main(String[] args) {
    AtomicInteger atomicInteger = new AtomicInteger(123);
    System.out.println(atomicInteger.get());

    int expectedValue = 123;
    int newValue   = 234;
    Boolean b =atomicInteger.compareAndSet(expectedValue, newValue);
    System.out.println(b);
    System.out.println(atomicInteger);

  }
-----》輸出結(jié)果為: 123 true 234

由上可知該方法表示,atomicInteger的值與expectedValue相比較,如果不相等,則返回false,
atomicInteger原有值保持不變;如果兩者相等,則返回true,atomicInteger的值更新為newValue

getAndAdd()方法與AddAndGet方法

AtomicInteger atomicInteger = new AtomicInteger(123);
    System.out.println(atomicInteger.get()); --123

    System.out.println(atomicInteger.getAndAdd(10)); --123 獲取當(dāng)前值,并加10
    System.out.println(atomicInteger.get()); --133


    System.out.println(atomicInteger.addAndGet(10)); --143 獲取加10后的值,先加10
    System.out.println(atomicInteger.get()); --143

getAndDecrement()和DecrementAndGet()方法

AtomicInteger atomicInteger = new AtomicInteger(123);
    System.out.println(atomicInteger.get());  --123
    System.out.println(atomicInteger.getAndDecrement()); --123 獲取當(dāng)前值并自減
    System.out.println(atomicInteger.get()); --122
    System.out.println(atomicInteger.decrementAndGet()); --121 先自減再獲取減1后的值
    System.out.println(atomicInteger.get()); --121

3、使用AtomicInteger,即使不用同步塊synchronized,最后的結(jié)果也是100,可用看出AtomicInteger的作用,用原子方式更新的int值。主要用于在高并發(fā)環(huán)境下的高效程序處理。使用非阻塞算法來(lái)實(shí)現(xiàn)并發(fā)控制。

public class Counter {

  public static AtomicInteger count = new AtomicInteger(0);

  public static void inc(){
    try{
      Thread.sleep(1); //延遲1毫秒

    }catch (InterruptedException e){ //catch住中斷異常,防止程序中斷
      e.printStackTrace();

    }
    count.getAndIncrement();//count值自加1
  }


  public static void main(String[] args) throws InterruptedException {


    final CountDownLatch latch = new CountDownLatch(100);

    for(int i=0;i<100;i++){
      new Thread(new Runnable() {
        @Override
        public void run() {
          Counter.inc();
          latch.countDown();
        }
      }).start();
    }
    latch.await();

    System.out.println("運(yùn)行結(jié)果:"+Counter.count);
  }
}

運(yùn)行結(jié)果: 100

4、使用普通Integer

public class Counter {

  public volatile static int count = 0;

  public static void inc(){
    try{
      Thread.sleep(1); //延遲1毫秒

    }catch (InterruptedException e){ //catch住中斷異常,防止程序中斷
      e.printStackTrace();

    }
    count++;//count值自加1
  }


  public static void main(String[] args) throws InterruptedException {


    final CountDownLatch latch = new CountDownLatch(100);

    for(int i=0;i<100;i++){
      new Thread(new Runnable() {
        @Override
        public void run() {
          Counter.inc();
          latch.countDown();
        }
      }).start();
    }
    latch.await();

    System.out.println("運(yùn)行結(jié)果:"+Counter.count);
  }
}
運(yùn)行結(jié)果:98

5、如果在inc方法前面加個(gè)synchronized也能是線程安全的;

它用來(lái)修飾一個(gè)方法或者一個(gè)代碼塊的時(shí)候,能夠保證在同一時(shí)刻最多只有一個(gè)線程執(zhí)行該段代碼。

import java.util.concurrent.CountDownLatch;
/**
 * created by guanguan on 2017/10/23
 **/
public class Counter {
   public volatile static Integer count = 0;
  public synchronized static void inc(){
    try{
      Thread.sleep(1); //延遲1毫秒
    }catch (InterruptedException e){ //catch住中斷異常,防止程序中斷
      e.printStackTrace();
    }
     count++;//count值自加1
  }
  public static void main(String[] args) throws InterruptedException {
    final CountDownLatch latch = new CountDownLatch(100);
    for(int i=0;i<100;i++){
      new Thread(new Runnable() {
        @Override
        public void run() {
          Counter.inc();
          latch.countDown();
        }
      }).start();
    }
    latch.await();
    System.out.println("運(yùn)行結(jié)果:"+Counter.count);
  }
}
運(yùn)行結(jié)果:100

synchronized的使用說(shuō)明:

一、當(dāng)兩個(gè)并發(fā)線程訪問(wèn)同一個(gè)對(duì)象object中的這個(gè)synchronized(this)同步代碼塊時(shí),一個(gè)時(shí)間內(nèi)只能有一個(gè)線程得到執(zhí)行。另一個(gè)線程必須等待當(dāng)前線程執(zhí)行完這個(gè)代碼塊以后才能執(zhí)行該代碼塊。

二、然而,當(dāng)一個(gè)線程訪問(wèn)object的一個(gè)synchronized(this)同步代碼塊時(shí),另一個(gè)線程仍然可以訪問(wèn)該object中的非synchronized(this)同步代碼塊。

三、尤其關(guān)鍵的是,當(dāng)一個(gè)線程訪問(wèn)object的一個(gè)synchronized(this)同步代碼塊時(shí),其他線程對(duì)object中所有其它synchronized(this)同步代碼塊的訪問(wèn)將被阻塞。

四、第三個(gè)例子同樣適用其它同步代碼塊。也就是說(shuō),當(dāng)一個(gè)線程訪問(wèn)object的一個(gè)synchronized(this)同步代碼塊時(shí),它就獲得了這個(gè)object的對(duì)象鎖。結(jié)果,其它線程對(duì)該object對(duì)象所有同步代碼部分的訪問(wèn)都被暫時(shí)阻塞。

五、以上規(guī)則對(duì)其它對(duì)象鎖同樣適用.

6、從上面的例子中我們可以看出:使用AtomicInteger是非常的安全的.而且因?yàn)锳tomicInteger由硬件提供原子操作指令實(shí)現(xiàn)的。在非激烈競(jìng)爭(zhēng)的情況下,開(kāi)銷更小,速度更快。

java的關(guān)鍵域有3個(gè)

// setup to use Unsafe.compareAndSwapInt for updates
private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final long valueOffset;
private volatile int value;

這里, unsafe是java提供的獲得對(duì)對(duì)象內(nèi)存地址訪問(wèn)的類,注釋已經(jīng)清楚的寫(xiě)出了,它的作用就是在更新操作時(shí)提供“比較并替換”的作用。實(shí)際上就是AtomicInteger中的一個(gè)工具。

valueOffset是用來(lái)記錄value本身在內(nèi)存的便宜地址的,這個(gè)記錄,也主要是為了在更新操作在內(nèi)存中找到value的位置,方便比較。

注意:value是用來(lái)存儲(chǔ)整數(shù)的時(shí)間變量,這里被聲明為volatile,就是為了保證在更新操作時(shí),當(dāng)前線程可以拿到value最新的值(并發(fā)環(huán)境下,value可能已經(jīng)被其他線程更新了)。

這里,我們以自增的代碼為例,可以看到這個(gè)并發(fā)控制的核心算法:

源碼

public final int updateAndGet(IntUnaryOperator updateFunction) {
    int prev, next;
    do {
      prev = get();
      next = updateFunction.applyAsInt(prev);
    } while (!compareAndSet(prev, next));
    return next;
  }

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • SpringBoot使用validation-api實(shí)現(xiàn)對(duì)枚舉類參數(shù)校驗(yàn)的方法

    SpringBoot使用validation-api實(shí)現(xiàn)對(duì)枚舉類參數(shù)校驗(yàn)的方法

    這篇文章主要介紹了SpringBoot使用validation-api實(shí)現(xiàn)對(duì)枚舉類參數(shù)校驗(yàn),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-11-11
  • Java?this關(guān)鍵字的使用案例詳解

    Java?this關(guān)鍵字的使用案例詳解

    這篇文章主要為大家介紹了Java?this關(guān)鍵字的使用,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-01-01
  • 詳解Java動(dòng)態(tài)代理的實(shí)現(xiàn)機(jī)制

    詳解Java動(dòng)態(tài)代理的實(shí)現(xiàn)機(jī)制

    這篇文章主要為大家詳細(xì)介紹了Java動(dòng)態(tài)代理的實(shí)現(xiàn)機(jī)制,感興趣的小伙伴們可以參考一下
    2016-03-03
  • Mybatis plus的自動(dòng)填充與樂(lè)觀鎖的實(shí)例詳解(springboot)

    Mybatis plus的自動(dòng)填充與樂(lè)觀鎖的實(shí)例詳解(springboot)

    這篇文章主要介紹了Mybatis plus的自動(dòng)填充與樂(lè)觀鎖的實(shí)例詳解(springboot),本文給大家介紹的非常詳細(xì)對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-11-11
  • SpringSecurity自定義登錄界面

    SpringSecurity自定義登錄界面

    這篇文章主要為大家詳細(xì)介紹了SpringSecurity自定義登錄界面,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-09-09
  • JAVA使用TreeMap對(duì)字符串進(jìn)行排序

    JAVA使用TreeMap對(duì)字符串進(jìn)行排序

    這篇文章主要介紹了JAVA使用TreeMap對(duì)字符串進(jìn)行排序,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-02-02
  • 一文告訴你為什么要重寫(xiě)hashCode()方法和equals()方法

    一文告訴你為什么要重寫(xiě)hashCode()方法和equals()方法

    本篇文章帶大家了解一下為什么重寫(xiě)hashCode()方法和equals()方法,文中有非常詳細(xì)的說(shuō)明以及代碼示例,對(duì)正在學(xué)習(xí)java的小伙伴們很有幫助,需要的朋友可以參考下
    2021-05-05
  • 淺談java中的聲明常量為什么要用static修飾

    淺談java中的聲明常量為什么要用static修飾

    這篇文章主要介紹了淺談java中的聲明常量為什么要用static修飾的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-09-09
  • 解決從Map、JSONObject取不存在鍵值對(duì)時(shí)的異常情況

    解決從Map、JSONObject取不存在鍵值對(duì)時(shí)的異常情況

    這篇文章主要介紹了解決從Map、JSONObject取不存在鍵值對(duì)時(shí)的異常情況,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • SpringBoot熱部署設(shè)置方法詳解

    SpringBoot熱部署設(shè)置方法詳解

    在實(shí)際開(kāi)發(fā)中,每次修改代碼就需要重啟項(xiàng)目,重新部署,對(duì)于一個(gè)后端開(kāi)發(fā)者來(lái)說(shuō),重啟確實(shí)很難受。在java開(kāi)發(fā)領(lǐng)域,熱部署一直是一個(gè)難以解決的問(wèn)題,目前java虛擬機(jī)只能實(shí)現(xiàn)方法體的熱部署,對(duì)于整個(gè)類的結(jié)構(gòu)修改,仍然需要重啟項(xiàng)目
    2022-10-10

最新評(píng)論