优秀的编程知识分享平台

网站首页 > 技术文章 正文

java基础第二弹int和Integer和AtomicInteger

nanyue 2024-07-29 01:07:19 技术文章 3 ℃

我们知道int是基本数据类型,Integer是其对应的包装类,既然是类,就可以用new来创建一个对象。

得益于java的自动拆箱和装箱,可以用==直接进行比较。

下面对两者进行对比:

  1. int是基本数据类型,Integer是它的包装类。
  2. int的默认值是0,Integer的默认值是null
  3. Integer是类,可以用new进行创建对象,当然该类里也有一些static方法可以直接使用。


在面试时,很多面试官都喜欢问,Integer是否有缓存?

答案是肯定的,下面来分析一下缓存是怎么用的。

private static class IntegerCache {
 static final int low = -128;
 static final int high;
 static final Integer cache[];
 static {
 // high value may be configured by property
 int h = 127;
 String integerCacheHighPropValue =
 sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
 if (integerCacheHighPropValue != null) {
 try {
 int i = parseInt(integerCacheHighPropValue);
 i = Math.max(i, 127);
 // Maximum array size is Integer.MAX_VALUE
 h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
 } catch( NumberFormatException nfe) {
 // If the property cannot be parsed into an int, ignore it.
 }
 }
 high = h;
 cache = new Integer[(high - low) + 1];
 int j = low;
 for(int k = 0; k < cache.length; k++)
 cache[k] = new Integer(j++);
 // range [-128, 127] must be interned (JLS7 5.1.7)
 assert IntegerCache.high >= 127;
 }
 private IntegerCache() {}
}

老规矩,跟着源码来分析。

从这段代码我们可以看出,如果没有在vm里设置过

java.lang.Integer.IntegerCache.high

这个属性的话,缓存的区间则为-128到127之间。

如果有设置这个值的话,则在该值和

Math.min(i, Integer.MAX_VALUE - (-low) -1)

两者之间取小。即可以是显示的修改缓存的上限,却无法修改下限值,不过一般也没有人会傻

到修改这个值,却不知道为什么有些面试官还喜欢问这个问题,意义是什么?

另外从这段代码可以看出,一旦该类被加载,则会直接把该数区间缓存起来。

那是在什么地方用到的呢?

public static Integer valueOf(int i) {
 if (i >= IntegerCache.low && i <= IntegerCache.high)
 return IntegerCache.cache[i + (-IntegerCache.low)];
 return new Integer(i);
}


从这里明显的可以看出来,也就是装箱的时候,先从缓存里查找,如果没有的话,在重新创建一个对象。这个缓存,只有在高频数据才有用,如果数据比较大的话,还是会直接创建。针对高频使用的数字,缓存才有意义。

AtomicInteger类,是JUC(java.util.concurrent)包里的一个类。从类名上也可以

是原子类型的类。

它是如何保证原子化操作的呢,从源码来分析一下。

简答的看下addAndGet这个方法,

public final int addAndGet(int delta) {
 return unsafe.getAndAddInt(this, valueOffset, delta) + delta;
}


进入unsafe,可以看到,这里是用的CAS锁来进行计算的。

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;
}

compareAndSwapInt是直接调用计算机的指令来进行计算的。

关于CAS,后面在进行详细的描述。

本文主要是帮助分析,算是个入门的文章,不会详细分析每个方法的用法等。

希望对初学者的你,有所帮助。

最近发表
标签列表