激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務(wù)器之家:專(zhuān)注于服務(wù)器技術(shù)及軟件下載分享
分類(lèi)導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語(yǔ)言|JavaScript|易語(yǔ)言|vb.net|

服務(wù)器之家 - 編程語(yǔ)言 - Java教程 - Java多線程CAS操作原理代碼實(shí)例解析

Java多線程CAS操作原理代碼實(shí)例解析

2020-07-26 00:03AmourLee Java教程

這篇文章主要介紹了Java多線程CAS操作原理代碼實(shí)例解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

CAS操作號(hào)稱(chēng)無(wú)鎖優(yōu)化,也叫作自旋;對(duì)于一些常見(jiàn)的操作需要加鎖,然后jdk就提供了一些以Atomic開(kāi)頭的類(lèi),這些類(lèi)內(nèi)部自動(dòng)帶了鎖,當(dāng)然這里的鎖并非是用synchronized來(lái)實(shí)現(xiàn)的,而是通過(guò)CAS操作來(lái)實(shí)現(xiàn)的;

一、下面是 AtomicInteger 的使用:

?
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
package com.designmodal.design.juc01;
 
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
 
/**
 * @author D-L
 * @Classname T03_AtomicInteger
 * @Version 1.0
 * @Description 使用 AtomicInteger 類(lèi)解決常見(jiàn)的 多線程count++
 *        其內(nèi)部使用了CAS操作來(lái)保證原子性 但是不能保證多個(gè)方法連續(xù)調(diào)用都是原子性
 * @Date 2020/7/21 0:35
 */
public class T03_AtomicInteger {
  //使用AtomicInteger類(lèi)
  AtomicInteger count = new AtomicInteger(0);
 
  public void m(){
    for (int i = 0; i < 10000; i++) {
      //等同于 在 count++ 上加鎖
      count.incrementAndGet();
    }
  }
 
  public static void main(String[] args) {
    T03_AtomicInteger t = new T03_AtomicInteger();
    List<Thread> threads = new ArrayList<>();
    for (int i = 0; i < 10; i++) {
      threads.add(new Thread(t::m , "Thread" + i));
    }
    threads.forEach((o) -> o.start());
    threads.forEach(o ->{
      try {
        o.join();
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    });
 
    System.out.println(t.count);
  }
}

二、當(dāng)然達(dá)到使用的級(jí)別很簡(jiǎn)單,看一下API就好了,通過(guò)上面的小程序,下面主要來(lái)聊一聊原理:

1、通過(guò)源碼分析AtomicInteger

首先小程序中定義了一個(gè) AtomicInteger 類(lèi)型的變量count;

?
1
2
3
4
AtomicInteger count = new AtomicInteger(0);
public void add(){
 count.incrementAndGet();
}

調(diào)用了AtomicInteger類(lèi)中incrementAndGet();

?
1
2
3
4
5
6
7
8
/**
   * Atomically increments by one the current value.
   *
   * @return the updated value
   */
  public final int incrementAndGet() {
    return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
  }

調(diào)用unsafe類(lèi)中的 getAndAddInt(Object var1, long var2, int var4)方法;

?
1
2
3
4
5
6
7
8
9
10
11
12
public native int getIntVolatile(Object var1, long var2);
public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);
 
 
 public final int getAndAddInt(Object var1, long var2, int var4) {
    int var5;
    do {
      var5 = this.getIntVolatile(var1, var2);
    } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));
 
    return var5;
  }

這里通過(guò)以上三步的操作,最終會(huì)進(jìn)入U(xiǎn)nsafe類(lèi)這里調(diào)用的 compareAndSwapInt 意思就是比較然后交換,通過(guò)一個(gè)while循環(huán),在這里轉(zhuǎn)呀轉(zhuǎn),直到修改成功;

CAS(compareAndSwap)(比較并交換):原來(lái)想改變的值為0 ,現(xiàn)在想修改成1 ,這里想做到線程安全就必須要加synchronized,現(xiàn)在想用另外一種方式來(lái)替換加鎖的方法,就是所謂的CAS操作;你可以把它想象成擁有三個(gè)參數(shù)的方法cas(V , Expected , NewValue); 第一個(gè)參數(shù)V是你要改的那個(gè)值,Expected第二個(gè)參數(shù)是你期望當(dāng)前的值是多少(也就是如果沒(méi)有線程修改的時(shí),這個(gè)值應(yīng)該是多少,如果不是期望值那就證明有別的線程修改過(guò)),NewValue是要設(shè)置的新值;

Java多線程CAS操作原理代碼實(shí)例解析

上圖簡(jiǎn)單模擬了CAS操作的過(guò)程,當(dāng)線程1和線程2同時(shí)讀取了共享變量count = 0;在線程1修改的過(guò)程中,線程2已經(jīng)將count值修改為1,那么在線程1修改的時(shí)候發(fā)現(xiàn)Expected值和V已經(jīng)匹配不上了,證明已經(jīng)有線程快我一步將count值改了(可能這里并發(fā)量大的時(shí)候已經(jīng)有n多個(gè)線程已經(jīng)修改過(guò)了),怎么辦呢?那我只能將我的期望值修改成V的值、newValue 在這基礎(chǔ)上加1,然后繼續(xù)在這自旋操作,直到修改成功,這就是自旋操作;

2、Unsafe類(lèi)(java并發(fā)包底層實(shí)現(xiàn)的核心)

CAS操作不需要加鎖是如何做到的呢?原因就在于Unsafe這個(gè)類(lèi),這個(gè)類(lèi)除了你使用反射之外,你是不能夠直接使用的,這里不能使用的原因和ClassLoader有關(guān)系,所有AtomicXXX 類(lèi)內(nèi)部都是CompareAndSwap / CompareAndSet(新版jdk),這個(gè)類(lèi)中存在好多native方法;

Unsafe類(lèi)使Java擁有了像C語(yǔ)言的指針一樣操作內(nèi)存空間的能力,一旦能夠直接操作內(nèi)存,這也就意味著(1)不受JVM管理,也就意味著無(wú)法被GC,需要我們手動(dòng)GC,稍有不慎就會(huì)出現(xiàn)內(nèi)存泄漏。(2)Unsafe的不少方法中必須提供原始地址(內(nèi)存地址)和被替換對(duì)象的地址,偏移量要自己計(jì)算,一旦出現(xiàn)問(wèn)題就是JVM崩潰級(jí)別的異常,會(huì)導(dǎo)致整個(gè)JVM實(shí)例崩潰,表現(xiàn)為應(yīng)用程序直接crash掉。(3)直接操作內(nèi)存,也意味著其速度更快,在高并發(fā)的條件之下能夠很好地提高效率。

CAS:CompareAndSwap,內(nèi)存偏移地址(var2),預(yù)期值(var4),新值(var5)。如果變量在當(dāng)前時(shí)刻的值和預(yù)期值expected相等,嘗試將變量的值更新為新值(var5)。如果更新成功,返回true;否則,返回false。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
   * CAS操作 :Unsafe類(lèi)中的本地方法 由于Java語(yǔ)言無(wú)法訪問(wèn)操作系統(tǒng)底層信息(比如:底層硬件設(shè)備等),
   * 這時(shí)候就需要借助C C++語(yǔ)言來(lái)完成了
   * @param var1 對(duì)象
   * @param var2 偏移量
   * @param var4 期望值
   * @param var5 新值
   * @return 修改成功返回true 失敗返回false
   */
  public final native boolean compareAndSwapObject(Object var1, long var2, Object var4, Object var5);
 
  public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);
 
  public final native boolean compareAndSwapLong(Object var1, long var2, long var4, long var6);

三、CAS操作帶來(lái)的ABA問(wèn)題

ABA問(wèn)題說(shuō)白了就是在線程進(jìn)行CAS操作過(guò)程中有多個(gè)線程對(duì)這個(gè)共享變量進(jìn)行修改,有加有減,兜兜轉(zhuǎn)轉(zhuǎn)又回到起始值,這時(shí)該線程渾然不知;打個(gè)不恰當(dāng)?shù)谋扔鳎哼@個(gè)過(guò)程就好像你前女友跟你分手以后,在時(shí)隔一年之后又找你復(fù)合來(lái)了,說(shuō)兜兜轉(zhuǎn)轉(zhuǎn)還是覺(jué)得你好,在此期間你前女友已經(jīng)換了幾個(gè)男朋友你卻渾然不知,那個(gè)好看的她穿著你喜歡的小短裙,扎著清純的馬尾辮又回來(lái),好了言歸正傳,意思就是結(jié)果是你期望的,可是這個(gè)值是經(jīng)過(guò)很多版本的。

下面簡(jiǎn)單模擬ABA操作圖:

Java多線程CAS操作原理代碼實(shí)例解析

如何解決ABA問(wèn)題呢?

如果是int類(lèi)型,最終的值也是你期望的,真的是沒(méi)有所謂,你也不用去糾結(jié)這問(wèn)題;如果你確實(shí)就想管一管,那就加一個(gè)版本號(hào),做一次修改操作加一,比較檢查時(shí)連帶版本號(hào)一起檢查。

基礎(chǔ)類(lèi)型:沒(méi)有必要管,對(duì)你真的沒(méi)有所謂;

引用類(lèi)型:就像是你女朋友和你分手之后又復(fù)合,中間經(jīng)歷了多少個(gè)男朋友,這個(gè)是有所謂的,這時(shí)可以通過(guò)加版本號(hào)來(lái)解決;

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

原文鏈接:https://www.cnblogs.com/dongl961230/p/13352744.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 91精品国产91久久久久久吃药 | 亚洲国产精品久久久久久久久久 | 国产精品久久久不卡 | 欧美日本色 | 大西瓜永久免费av在线 | 国产羞羞视频在线观看 | 久久久资源网 | 亚洲成人精品久久久 | 农村寡妇偷毛片一级 | www日韩大片 | 舌头伸进添的我好爽高潮网站 | 91精品国产手机 | 亚洲精华液久久含羞草 | 草操影院 | javhdfreejaⅴhd | 18欧美性xxxx极品hd | 最新久久免费视频 | 91短视频版高清在线观看免费 | 国产毛片视频在线 | 国产精品免费一区二区三区在线观看 | 国产精品久久久久网站 | 中文日韩欧美 | 国产91极品| 精品1| 香蕉久久久久 | 国产色视频免费 | 黄色1级视频 | 欧美黄色一级生活片 | 免费看一级视频 | 免费国产网站 | 成人精品视频在线 | 欧美精品成人一区二区三区四区 | 亚洲精品无码不卡在线播放he | 欧美成人免费在线视频 | 中文字幕线观看 | 精品一区二区三区中文字幕 | 特黄一级小说 | 夜夜夜操操操 | 国产毛片毛片毛片 | 欧美乱码精品一区 | 九九黄色 |