Java开发,参数类型如何选?int, Integer, AtomicInteger?

本文详细介绍了Java中的int、Integer和AtomicInteger类型,讨论了它们在性能、封装、缓存池和并发编程中的应用,重点强调了AtomicInteger的原子性和CAS操作在避免锁竞争中的重要性。

背景

如题所述,笔者在前段时间面试某家金融科技公司时被问到了上述问题,脑海中的记忆一时也不是太清楚,特地前来进行整理并分享。


概述

int是基础的变量类型;Integer是包装类型;AtomicInteger是来自JUC的一个在并发编程场景下重要的包,对于Java开发人员来说,确实需要对其都有充分的认识与了解。

int

int 是 Java 的基本数据类型,它是一个 32 位的有符号整数,取值范围为 -2^31 到
2^31-1。
int 类型在性能上比 Integer 和 AtomicInteger 更优越,因为它是一个简单的原生类型,没有额外的封装和开销。

Integer

首先,Integer属于包装类。包装类型的出现就是我们可以在对象里面定义一些方法,因为封装的数据类型就是一个对象,可以拥有属性和方法,有了这些属性和方法我们就可以用它们来处理数据,比如Integer对象里的parseInt(String s),可以把字符串转换成int类型等。

Integer x = 2;     // 装箱 调用了 Integer.valueOf(2)
int y = x;         // 拆箱 调用了 X.intValue()

Integer 是 Java 的一个包装类,它对应的基本类型是 int。**Integer 类型的所有实例都共享一个静态的缓存池,用于存储 int 类型的值。**当需要使用一个整数时,Java 会优先从缓存池中获取一个已有的 Integer 实例,而不会创建一个新的实例。这样可以提高性能,尤其是在处理大量整数时。

Integer 和 int的区别?

  • Integer是int的包装类,int则是java的一种基本的数据类型;

  • Integer变量必须实例化之后才能使用,而int变量不需要实例化;

  • Integer实际是对象的引用,当new一个Integer时,实际上生成一个指针指向对象,而int则直接存储数值

  • Integer的默认值是null,而int的默认值是0。

  • 包装类Integer和基本数据类型比较的时候,java会自动拆箱为int,然后进行比较

缓存池

基本类型对应的缓冲池如下

Java 基本类型的包装类的大部分都实现了常量池技术,即Byte,Short,Integer,Long,Character,Boolean;

  • 前4 种包装类默认创建了数值[-128,127] 的相应类型的缓存数据
  • Character创建了数值在[0,127]范围的缓存数据
  • Boolean 直接返回True 或 False。如果超出对应范围仍然会去创建新的对象。

在使用这些基本类型对应的包装类型时,如果该数值范围在缓冲池范围内,就可以直接使用缓冲池中的对象。

在 jdk 1.8 所有的数值类缓冲池中,Integer 的缓冲池 IntegerCache 很特

除了`AtomicInteger`之外,Java 中的原子类根据功能可以分为以下几类 [^1]: ### Atomic 基本类型原子类 - **AtomicBoolean**:以原子方式更新布尔值。 ```java import java.util.concurrent.atomic.AtomicBoolean; public class AtomicBooleanExample { public static void main(String[] args) { AtomicBoolean atomicBoolean = new AtomicBoolean(false); boolean result = atomicBoolean.compareAndSet(false, true); System.out.println("Updated: " + result); System.out.println("Value: " + atomicBoolean.get()); } } ``` - **AtomicLong**:以原子方式更新长整型值。 ```java import java.util.concurrent.atomic.AtomicLong; public class AtomicLongExample { public static void main(String[] args) { AtomicLong atomicLong = new AtomicLong(100L); long incremented = atomicLong.incrementAndGet(); System.out.println("Incremented value: " + incremented); } } ``` ### Array 数组类型原子类 - **AtomicIntegerArray**:以原子方式更新整型数组里的元素。 ```java import java.util.concurrent.atomic.AtomicIntegerArray; public class AtomicIntegerArrayExample { public static void main(String[] args) { int[] array = {1, 2, 3}; AtomicIntegerArray atomicIntegerArray = new AtomicIntegerArray(array); atomicIntegerArray.getAndAdd(1, 5); System.out.println("Updated array element: " + atomicIntegerArray.get(1)); } } ``` - **AtomicLongArray**:以原子方式更新长整型数组里的元素。 ```java import java.util.concurrent.atomic.AtomicLongArray; public class AtomicLongArrayExample { public static void main(String[] args) { long[] array = {1L, 2L, 3L}; AtomicLongArray atomicLongArray = new AtomicLongArray(array); atomicLongArray.getAndAdd(2, 10L); System.out.println("Updated array element: " + atomicLongArray.get(2)); } } ``` - **AtomicReferenceArray**:以原子方式更新引用类型数组里的元素。 ```java import java.util.concurrent.atomic.AtomicReferenceArray; public class AtomicReferenceArrayExample { public static void main(String[] args) { String[] array = {"a", "b", "c"}; AtomicReferenceArray<String> atomicReferenceArray = new AtomicReferenceArray<>(array); atomicReferenceArray.getAndSet(1, "new"); System.out.println("Updated array element: " + atomicReferenceArray.get(1)); } } ``` ### AtomicReference 引用类型原子类 - **AtomicReference**:以原子方式更新引用类型。 ```java import java.util.concurrent.atomic.AtomicReference; class User { String name; User(String name) { this.name = name; } } public class AtomicReferenceExample { public static void main(String[] args) { User user1 = new User("Alice"); AtomicReference<User> atomicReference = new AtomicReference<>(user1); User user2 = new User("Bob"); atomicReference.set(user2); System.out.println("Updated user name: " + atomicReference.get().name); } } ``` - **AtomicStampedReference**:带有版本号的引用类型原子类,可以解决 ABA 问题。 ```java import java.util.concurrent.atomic.AtomicStampedReference; public class AtomicStampedReferenceExample { public static void main(String[] args) { Integer initialRef = 100; Integer initialStamp = 0; AtomicStampedReference<Integer> atomicStampedReference = new AtomicStampedReference<>(initialRef, initialStamp); int[] stampHolder = new int[1]; Integer reference = atomicStampedReference.get(stampHolder); int stamp = stampHolder[0]; boolean result = atomicStampedReference.compareAndSet(reference, 200, stamp, stamp + 1); System.out.println("Update result: " + result); } } ``` - **AtomicMarkableReference** :带有标记位的引用类型原子类。 ```java import java.util.concurrent.atomic.AtomicMarkableReference; public class AtomicMarkableReferenceExample { public static void main(String[] args) { String initialRef = "value"; boolean initialMark = false; AtomicMarkableReference<String> atomicMarkableReference = new AtomicMarkableReference<>(initialRef, initialMark); boolean[] markHolder = new boolean[1]; String reference = atomicMarkableReference.get(markHolder); boolean mark = markHolder[0]; boolean result = atomicMarkableReference.compareAndSet(reference, "newValue", mark, !mark); System.out.println("Update result: " + result); } } ``` ### AtomicFieldUpdater 原子更新属性 - **AtomicIntegerFieldUpdater**:原子更新整型字段的更新器。 ```java import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; class MyClass { volatile int value; } public class AtomicIntegerFieldUpdaterExample { public static void main(String[] args) { MyClass myClass = new MyClass(); AtomicIntegerFieldUpdater<MyClass> updater = AtomicIntegerFieldUpdater.newUpdater(MyClass.class, "value"); updater.getAndIncrement(myClass); System.out.println("Updated value: " + myClass.value); } } ``` - **AtomicLongFieldUpdater**:原子更新长整型字段的更新器。 ```java import java.util.concurrent.atomic.AtomicLongFieldUpdater; class MyLongClass { volatile long value; } public class AtomicLongFieldUpdaterExample { public static void main(String[] args) { MyLongClass myLongClass = new MyLongClass(); AtomicLongFieldUpdater<MyLongClass> updater = AtomicLongFieldUpdater.newUpdater(MyLongClass.class, "value"); updater.getAndIncrement(myLongClass); System.out.println("Updated value: " + myLongClass.value); } } ``` - **AtomicReferenceFieldUpdater**:原子更新引用类型字段的更新器。 ```java import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; class MyRefClass { volatile String value; } public class AtomicReferenceFieldUpdaterExample { public static void main(String[] args) { MyRefClass myRefClass = new MyRefClass(); AtomicReferenceFieldUpdater<MyRefClass, String> updater = AtomicReferenceFieldUpdater.newUpdater(MyRefClass.class, String.class, "value"); updater.getAndSet(myRefClass, "newValue"); System.out.println("Updated value: " + myRefClass.value); } } ``` ### Adder 加法器 - **LongAdder**:用于高并发场景下的长整型累加器,性能比`AtomicLong`更高。 ```java import java.util.concurrent.atomic.LongAdder; public class LongAdderExample { public static void main(String[] args) { LongAdder longAdder = new LongAdder(); longAdder.add(10); System.out.println("Sum: " + longAdder.sum()); } } ``` - **DoubleAdder**:用于高并发场景下的双精度浮点型累加器。 ```java import java.util.concurrent.atomic.DoubleAdder; public class DoubleAdderExample { public static void main(String[] args) { DoubleAdder doubleAdder = new DoubleAdder(); doubleAdder.add(10.5); System.out.println("Sum: " + doubleAdder.sum()); } } ``` ### Accumulator 积累器 - **LongAccumulator**:一个通用的长整型积累器。 ```java import java.util.concurrent.atomic.LongAccumulator; public class LongAccumulatorExample { public static void main(String[] args) { LongAccumulator accumulator = new LongAccumulator((x, y) -> x + y, 0L); accumulator.accumulate(10L); System.out.println("Result: " + accumulator.get()); } } ``` - **DoubleAccumulator**:一个通用的双精度浮点型积累器。 ```java import java.util.concurrent.atomic.DoubleAccumulator; public class DoubleAccumulatorExample { public static void main(String[] args) { DoubleAccumulator accumulator = new DoubleAccumulator((x, y) -> x + y, 0.0); accumulator.accumulate(10.5); System.out.println("Result: " + accumulator.get()); } } ```
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值