java-i++和++i從jvm層面解釋

代碼如下:

public static void main(String arg[]) {
        int a  = 0;
        a++;
        System.out.println(a);

        int b = 0;
        ++b;
        System.out.println(b);

        int c = 0;
        System.out.println(b++);

        int d = 0;
        System.out.println(++d);
    }

查看編譯后的class文件

查看方式:可以直接使用命令:javap -v main.class颠悬。或者使用idea擴(kuò)展插件jclasslib讼溺。使用方法可以自己百度吧璃搜。我不經(jīng)常查看class文件庐橙,是使用的是命令。下面是完整的輸出結(jié)果

Classfile /E:/MyProject/kite-school/kite-school-security/target/classes/com/school/mainTest.class
  Last modified 2020年12月7日; size 854 bytes
  MD5 checksum 6687beca749c37871dca7cd1caba837c
  Compiled from "mainTest.java"
public class com.school.mainTest
  minor version: 0
  major version: 52
  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
  this_class: #4                          // com/school/mainTest
  super_class: #5                         // java/lang/Object
  interfaces: 0, fields: 0, methods: 2, attributes: 2
Constant pool:
   #1 = Methodref          #5.#31         // java/lang/Object."<init>":()V
   #2 = Fieldref           #32.#33        // java/lang/System.out:Ljava/io/PrintStream;
   #3 = Methodref          #34.#35        // java/io/PrintStream.println:(I)V
   #4 = Class              #36            // com/school/mainTest
   #5 = Class              #37            // java/lang/Object
   #6 = Class              #38            // com/school/mainTest$1
   #7 = Utf8               InnerClasses
   #8 = Class              #39            // com/school/mainTest$ObjectClass
   #9 = Utf8               ObjectClass
  #10 = Class              #40            // com/school/mainTest$ClassTest
  #11 = Utf8               ClassTest
  #12 = Utf8               <init>
  #13 = Utf8               ()V
  #14 = Utf8               Code
  #15 = Utf8               LineNumberTable
  #16 = Utf8               LocalVariableTable
  #17 = Utf8               this
  #18 = Utf8               Lcom/school/mainTest;
  #19 = Utf8               main
  #20 = Utf8               ([Ljava/lang/String;)V
  #21 = Utf8               arg
  #22 = Utf8               [Ljava/lang/String;
  #23 = Utf8               a
  #24 = Utf8               I
  #25 = Utf8               b
  #26 = Utf8               c
  #27 = Utf8               d
  #28 = Utf8               MethodParameters
  #29 = Utf8               SourceFile
  #30 = Utf8               mainTest.java
  #31 = NameAndType        #12:#13        // "<init>":()V
  #32 = Class              #41            // java/lang/System
  #33 = NameAndType        #42:#43        // out:Ljava/io/PrintStream;
  #34 = Class              #44            // java/io/PrintStream
  #35 = NameAndType        #45:#46        // println:(I)V
  #36 = Utf8               com/school/mainTest
  #37 = Utf8               java/lang/Object
  #38 = Utf8               com/school/mainTest$1
  #39 = Utf8               com/school/mainTest$ObjectClass
  #40 = Utf8               com/school/mainTest$ClassTest
  #41 = Utf8               java/lang/System
  #42 = Utf8               out
  #43 = Utf8               Ljava/io/PrintStream;
  #44 = Utf8               java/io/PrintStream
  #45 = Utf8               println
  #46 = Utf8               (I)V
{
  public com.school.mainTest();
    descriptor: ()V
    flags: (0x0001) ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: return
      LineNumberTable:
        line 17: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   Lcom/school/mainTest;

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=5, args_size=1
         0: iconst_0
         1: istore_1
         2: iinc          1, 1
         5: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
         8: iload_1
         9: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V
        12: iconst_0
        13: istore_2
        14: iinc          2, 1
        17: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
        20: iload_2
        21: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V
        24: iconst_0
        25: istore_3
        26: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
        29: iload_2
        30: iinc          2, 1
        33: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V
        36: iconst_0
        37: istore        4
        39: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
        42: iinc          4, 1
        45: iload         4
        47: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V
        50: return
      LineNumberTable:
        line 33: 0
        line 34: 2
        line 35: 5
        line 37: 12
        line 38: 14
        line 39: 17
        line 41: 24
        line 42: 26
        line 44: 36
        line 45: 39
        line 46: 50
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      51     0   arg   [Ljava/lang/String;
            2      49     1     a   I
           14      37     2     b   I
           26      25     3     c   I
           39      12     4     d   I
    MethodParameters:
      Name                           Flags
      arg
}
SourceFile: "mainTest.java"
InnerClasses:
  static #6;                              // class com/school/mainTest$1
  static #11= #10 of #4;                  // ClassTest=class com/school/mainTest$ClassTest of class com/school/mainTest

重點(diǎn):

%DHAY97J{)VT54QE4GA2N5W.png

可以看到i++和++i的不同主要在于對操作數(shù)棧和局部變量表的操作順序不同怯伊,導(dǎo)致當(dāng)操作i的時候琳轿,發(fā)現(xiàn)i的值有所不同。這里大家可以參考下面的命令解釋耿芹,然后再仔細(xì)看看我的截圖崭篡,就會有很好的了解。更多的 指令集見:java class源文件指令集解釋

使用命令解釋

D5982X30(X7H2$Q{2(2~%BT.jpg

i++和++i線程安全問題

i++和++i的線程安全分為兩種情況:
1猩系、如果i是局部變量(在方法里定義的)媚送,那么是線程安全的。因?yàn)榫植孔兞渴蔷€程私有的寇甸,別的線程訪問不到塘偎,其實(shí)也可以說沒有線程安不安全之說,因?yàn)閯e的線程對他造不成影響拿霉。
2吟秩、如果i是全局變量(類的成員變量),那么是線程不安全的绽淘。因?yàn)槿绻侨肿兞康脑捄溃贿M(jìn)程中的不同線程都有可能訪問到。

可以使用Synchronized鎖或者Lock接口的實(shí)現(xiàn)類鎖沪铭,都可以

如果有大量線程同時執(zhí)行i++操作壮池,i變量的副本拷貝到每個線程的線程棧偏瓤,當(dāng)同時有兩個線程棧以上的線程讀取線程變量,假如此時是1的話椰憋,那么同時執(zhí)行i++操作厅克,再寫入到全局變量,最后兩個線程執(zhí)行完橙依,i會等于3而不會是2证舟,所以,出現(xiàn)不安全性窗骑。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末女责,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子创译,更是在濱河造成了極大的恐慌抵知,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件昔榴,死亡現(xiàn)場離奇詭異辛藻,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)互订,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進(jìn)店門吱肌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人仰禽,你說我怎么就攤上這事氮墨。” “怎么了吐葵?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵规揪,是天一觀的道長。 經(jīng)常有香客問我温峭,道長猛铅,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任凤藏,我火速辦了婚禮奸忽,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘揖庄。我一直安慰自己栗菜,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布蹄梢。 她就那樣靜靜地躺著疙筹,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上而咆,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天霍比,我揣著相機(jī)與錄音,去河邊找鬼翘盖。 笑死桂塞,一個胖子當(dāng)著我的面吹牛凹蜂,可吹牛的內(nèi)容都是我干的馍驯。 我是一名探鬼主播,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼玛痊,長吁一口氣:“原來是場噩夢啊……” “哼汰瘫!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起擂煞,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤混弥,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后对省,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蝗拿,經(jīng)...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年蒿涎,在試婚紗的時候發(fā)現(xiàn)自己被綠了哀托。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,115評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡劳秋,死狀恐怖仓手,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情玻淑,我是刑警寧澤嗽冒,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站补履,受9級特大地震影響添坊,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜箫锤,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一贬蛙、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧麻汰,春花似錦速客、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春浪耘,著一層夾襖步出監(jiān)牢的瞬間乱灵,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工七冲, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留痛倚,地道東北人。 一個月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓澜躺,卻偏偏與公主長得像蝉稳,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子掘鄙,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評論 2 355

推薦閱讀更多精彩內(nèi)容