• 自动包装机制Integer,与AtomicReference<Integer>的问题


    从如下代码开始了解Integer的自动包装机制

     1 import java.util.concurrent.atomic.AtomicInteger;
     2 import java.util.concurrent.atomic.AtomicReference;
     3 
     4 /**
     5  * 比较方法一与方法二的区别
     6  */
     7 public class AtomicIntegerDemo {
     8 
     9     static void demo1(){
    10         AtomicInteger atomicInteger = new AtomicInteger(100);
    11         atomicInteger.compareAndSet(100, 200);
    12         atomicInteger.compareAndSet(200, 400);
    13         System.out.println(atomicInteger.get());
    14     }
    15 
    16     /**
    17      * 需要仔细了解此例输出
    18      */
    19     static void demo2(){
    20         AtomicReference<Integer> atomicReference = new AtomicReference<>(100);
    21         atomicReference.compareAndSet(100, 200);
    22         atomicReference.compareAndSet(200, 400);
    23         System.out.println(atomicReference.get());
    24     }
    25     
    26     public static void main(String[] args) {
    27         demo1();
    28         demo2();
    29     }
    30 }

    此代码的输出如下:

    400
    200
    
    Process finished with exit code 0

    预期demo2()方法最终输出400,但结果并不是。

    问题根源,自动包装机制:

     1 public final class Integer extends Number implements Comparable<Integer> {
     2     /**
     3      * The value of the {@code Integer}.
     4      *
     5      * @serial
     6      */
     7     private final int value;
     8 
     9     /**
    10      * Returns an {@code Integer} instance representing the specified
    11      * {@code int} value.  If a new {@code Integer} instance is not
    12      * required, this method should generally be used in preference to
    13      * the constructor {@link #Integer(int)}, as this method is likely
    14      * to yield significantly better space and time performance by
    15      * caching frequently requested values.
    16      *
    17      * This method will always cache values in the range -128 to 127,
    18      * inclusive, and may cache other values outside of this range.
    19      *
    20      * @param  i an {@code int} value.
    21      * @return an {@code Integer} instance representing {@code i}.
    22      * @since  1.5
    23      */
    24     public static Integer valueOf(int i) {
    25         if (i >= IntegerCache.low && i <= IntegerCache.high)
    26             return IntegerCache.cache[i + (-IntegerCache.low)];
    27         return new Integer(i);
    28     }
    29     /**
    30      * Cache to support the object identity semantics of autoboxing for values between
    31      * -128 and 127 (inclusive) as required by JLS.
    32      *
    33      * The cache is initialized on first usage.  The size of the cache
    34      * may be controlled by the {@code -XX:AutoBoxCacheMax=<size>} option.
    35      * During VM initialization, java.lang.Integer.IntegerCache.high property
    36      * may be set and saved in the private system properties in the
    37      * sun.misc.VM class.
    38      */
    39 
    40     private static class IntegerCache {
    41         static final int low = -128;
    42         static final int high;
    43         static final Integer cache[];
    44         . . .
    45     }
    46 . . .
    47 }

    AtomicReference中对象的比较为地址的比较。对于int字面量java会进行装箱将其转换成Integer对象,调用的是Integer.valueOf方法, 看源码你就明白了,128以内的会使用缓存,同一个int字面量返回同一个对象用==比较为true,而超过128返回不是同一个对象,==为false,equal才是true。

    本文结束。

  • 相关阅读:
    2016.7.22.noip2012D2
    2016.7.21.noip2014D2
    LIS最长上升子序列O(n^2)与O(nlogn)的算法
    vijos1910解方程
    vijos1909寻找道路
    viojs1908无线网路发射器选址
    P1907飞扬的小鸟
    P1906联合权值
    P1905生活大爆炸版 石头剪刀布
    poj1274(匈牙利算法)
  • 原文地址:https://www.cnblogs.com/yelao/p/12592403.html
Copyright © 2020-2023  润新知