AtomicInteger实现和代码复制?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (82)
public final int addAndGet(int delta) {
    for (;;) {
        int current = get();
        int next = current + delta;         // Only difference
        if (compareAndSet(current, next))
            return next;
    }
}

public final int incrementAndGet() {
    for (;;) {
        int current = get();
        int next = current + 1;             // Only difference
        if (compareAndSet(current, next))
            return next;
    }
}

显然,第二种方法可以写成:

public final int incrementAndGet() {
    return addAndGet(1);
}

为什么(或在什么情况下)第一段代码的性能要比第二段代码更好?

提问于
用户回答回答于
public final int addAndGet(int);
   ...
   4:   istore_2
   5:   iload_2
   6:   iload_1
   7:   iadd

public final int incrementAndGet();
   ...
   4:   istore_1
   5:   iload_1
   6:   iconst_1
   7:   iadd
用户回答回答于
  # {method} 'incrementAndGet' '()I' in 'java/util/concurrent/atomic/AtomicInteger'
  #           [sp+0x20]  (sp of caller)
  0x00000000026804c0: mov    r10d,DWORD PTR [rdx+0x8]
  0x00000000026804c4: shl    r10,0x3
  0x00000000026804c8: cmp    rax,r10
  0x00000000026804cb: jne    0x0000000002657b60  ;   {runtime_call}
  0x00000000026804d1: data32 xchg ax,ax
  0x00000000026804d4: nop    DWORD PTR [rax+rax*1+0x0]
  0x00000000026804dc: data32 data32 xchg ax,ax
[Verified Entry Point]
  0x00000000026804e0: sub    rsp,0x18
  0x00000000026804e7: mov    QWORD PTR [rsp+0x10],rbp  ;*synchronization entry
                                                ; - java.util.concurrent.atomic.AtomicInteger::incrementAndGet@-1 (line 204)
  0x00000000026804ec: mov    eax,DWORD PTR [rdx+0xc]  ;*invokevirtual compareAndSwapInt
                                                ; - java.util.concurrent.atomic.AtomicInteger::compareAndSet@9 (line 135)
                                                ; - java.util.concurrent.atomic.AtomicInteger::incrementAndGet@12 (line 206)
  0x00000000026804ef: mov    r8d,eax
  0x00000000026804f2: inc    r8d                ;*iadd
                                                ; - java.util.concurrent.atomic.AtomicInteger::incrementAndGet@7 (line 205)
  0x00000000026804f5: lock cmpxchg DWORD PTR [rdx+0xc],r8d
  0x00000000026804fb: sete   r11b
  0x00000000026804ff: movzx  r11d,r11b          ;*invokevirtual compareAndSwapInt
                                                ; - java.util.concurrent.atomic.AtomicInteger::compareAndSet@9 (line 135)
                                                ; - java.util.concurrent.atomic.AtomicInteger::incrementAndGet@12 (line 206)
  0x0000000002680503: test   r11d,r11d
  0x0000000002680506: je     0x0000000002680520  ;*iload_2
                                                ; - java.util.concurrent.atomic.AtomicInteger::incrementAndGet@18 (line 207)
  0x0000000002680508: mov    eax,r8d
  0x000000000268050b: add    rsp,0x10
  0x000000000268050f: pop    rbp
  0x0000000002680510: test   DWORD PTR [rip+0xfffffffffdbafaea],eax        # 0x0000000000230000
                                                ;   {poll_return}
  0x0000000002680516: ret    
  0x0000000002680517: nop    WORD PTR [rax+rax*1+0x0]  ; OopMap{rdx=Oop off=96}
                                                ;*goto
                                                ; - java.util.concurrent.atomic.AtomicInteger::incrementAndGet@20 (line 208)
  0x0000000002680520: test   DWORD PTR [rip+0xfffffffffdbafada],eax        # 0x0000000000230000
                                                ;*goto
                                                ; - java.util.concurrent.atomic.AtomicInteger::incrementAndGet@20 (line 208)
                                                ;   {poll}
  0x0000000002680526: mov    r11d,DWORD PTR [rdx+0xc]  ;*invokevirtual compareAndSwapInt
                                                ; - java.util.concurrent.atomic.AtomicInteger::compareAndSet@9 (line 135)
                                                ; - java.util.concurrent.atomic.AtomicInteger::incrementAndGet@12 (line 206)
  0x000000000268052a: mov    r8d,r11d
  0x000000000268052d: inc    r8d                ;*iadd
                                                ; - java.util.concurrent.atomic.AtomicInteger::incrementAndGet@7 (line 205)
  0x0000000002680530: mov    eax,r11d
  0x0000000002680533: lock cmpxchg DWORD PTR [rdx+0xc],r8d
  0x0000000002680539: sete   r11b
  0x000000000268053d: movzx  r11d,r11b          ;*invokevirtual compareAndSwapInt
                                                ; - java.util.concurrent.atomic.AtomicInteger::compareAndSet@9 (line 135)
                                                ; - java.util.concurrent.atomic.AtomicInteger::incrementAndGet@12 (line 206)
  0x0000000002680541: test   r11d,r11d
  0x0000000002680544: je     0x0000000002680520  ;*ifeq
                                                ; - java.util.concurrent.atomic.AtomicInteger::incrementAndGet@15 (line 206)
  0x0000000002680546: jmp    0x0000000002680508

完整列表(AddAndGet):

  # {method} 'addAndGet' '(I)I' in 'java/util/concurrent/atomic/AtomicInteger'
  # this:     rdx:rdx   = 'java/util/concurrent/atomic/AtomicInteger'
  # parm0:    r8        = int
  #           [sp+0x20]  (sp of caller)
  0x0000000002680d00: mov    r10d,DWORD PTR [rdx+0x8]
  0x0000000002680d04: shl    r10,0x3
  0x0000000002680d08: cmp    rax,r10
  0x0000000002680d0b: jne    0x0000000002657b60  ;   {runtime_call}
  0x0000000002680d11: data32 xchg ax,ax
  0x0000000002680d14: nop    DWORD PTR [rax+rax*1+0x0]
  0x0000000002680d1c: data32 data32 xchg ax,ax
[Verified Entry Point]
  0x0000000002680d20: sub    rsp,0x18
  0x0000000002680d27: mov    QWORD PTR [rsp+0x10],rbp  ;*synchronization entry
                                                ; - java.util.concurrent.atomic.AtomicInteger::addAndGet@-1 (line 233)
  0x0000000002680d2c: mov    eax,DWORD PTR [rdx+0xc]  ;*invokevirtual compareAndSwapInt
                                                ; - java.util.concurrent.atomic.AtomicInteger::compareAndSet@9 (line 135)
                                                ; - java.util.concurrent.atomic.AtomicInteger::addAndGet@12 (line 235)
  0x0000000002680d2f: mov    r9d,r8d
  0x0000000002680d32: add    r9d,eax            ;*iadd
                                                ; - java.util.concurrent.atomic.AtomicInteger::addAndGet@7 (line 234)
  0x0000000002680d35: lock cmpxchg DWORD PTR [rdx+0xc],r9d
  0x0000000002680d3b: sete   r11b
  0x0000000002680d3f: movzx  r11d,r11b          ;*invokevirtual compareAndSwapInt
                                                ; - java.util.concurrent.atomic.AtomicInteger::compareAndSet@9 (line 135)
                                                ; - java.util.concurrent.atomic.AtomicInteger::addAndGet@12 (line 235)
  0x0000000002680d43: test   r11d,r11d
  0x0000000002680d46: je     0x0000000002680d60  ;*iload_3
                                                ; - java.util.concurrent.atomic.AtomicInteger::addAndGet@18 (line 236)
  0x0000000002680d48: mov    eax,r9d
  0x0000000002680d4b: add    rsp,0x10
  0x0000000002680d4f: pop    rbp
  0x0000000002680d50: test   DWORD PTR [rip+0xfffffffffdbaf2aa],eax        # 0x0000000000230000
                                                ;   {poll_return}
  0x0000000002680d56: ret    
  0x0000000002680d57: nop    WORD PTR [rax+rax*1+0x0]  ; OopMap{rdx=Oop off=96}
                                                ;*goto
                                                ; - java.util.concurrent.atomic.AtomicInteger::addAndGet@20 (line 237)
  0x0000000002680d60: test   DWORD PTR [rip+0xfffffffffdbaf29a],eax        # 0x0000000000230000
                                                ;*goto
                                                ; - java.util.concurrent.atomic.AtomicInteger::addAndGet@20 (line 237)
                                                ;   {poll}
  0x0000000002680d66: mov    r11d,DWORD PTR [rdx+0xc]  ;*invokevirtual compareAndSwapInt
                                                ; - java.util.concurrent.atomic.AtomicInteger::compareAndSet@9 (line 135)
                                                ; - java.util.concurrent.atomic.AtomicInteger::addAndGet@12 (line 235)
  0x0000000002680d6a: mov    r9d,r11d
  0x0000000002680d6d: add    r9d,r8d            ;*iadd
                                                ; - java.util.concurrent.atomic.AtomicInteger::addAndGet@7 (line 234)
  0x0000000002680d70: mov    eax,r11d
  0x0000000002680d73: lock cmpxchg DWORD PTR [rdx+0xc],r9d
  0x0000000002680d79: sete   r11b
  0x0000000002680d7d: movzx  r11d,r11b          ;*invokevirtual compareAndSwapInt
                                                ; - java.util.concurrent.atomic.AtomicInteger::compareAndSet@9 (line 135)
                                                ; - java.util.concurrent.atomic.AtomicInteger::addAndGet@12 (line 235)
  0x0000000002680d81: test   r11d,r11d
  0x0000000002680d84: je     0x0000000002680d60  ;*ifeq
                                                ; - java.util.concurrent.atomic.AtomicInteger::addAndGet@15 (line 235)
  0x0000000002680d86: jmp    0x0000000002680d48

所属标签

可能回答问题的人

  • 女淘日记

    杭州吱吱吱科技 · 站长 (已认证)

    1 粉丝1 提问3 回答
  • 朝夕熊博客

    1 粉丝2 提问3 回答
  • gulu丶咕噜

    0 粉丝1 提问2 回答
  • o o

    4 粉丝495 提问2 回答

扫码关注云+社区

领取腾讯云代金券