好久没有进行输入了,之前很长一段时间都在输出过往的leetCode题解,但是,越输出越觉得自己心里很慌,其主要原因在于我输出的都是我已经会的了,然而我还是花了很长时间来输出了,主要是为了帮助需要的人,当然了,也是为了我自己日后看方便了很多,这不,在我输出160篇题解后,我还是找一点自己喜欢的内容,做下内容,其实也是便于自己更加的理解,这不,我来看AtomicInteger原子类的源码了。
正如开头所陈述的那样,我们为什么要是用AtomicInteger原子类?我们不妨看下下面的一段程序运行的结果吧。
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@Slf4j
public class AtomicIntegerTest {
private static int count = 0;
public static void main(String[] args) {
final int cycleCount = 1000;
CountDownLatch countDownLatch = new CountDownLatch(2);
ExecutorService executorService = Executors.newFixedThreadPool(2);
executorService.submit(() -> {
for (int i = 0; i < cycleCount; i++) {
count++;
}
countDownLatch.countDown();
});
executorService.submit(() -> {
for (int i = 0; i < cycleCount; i++) {
count++;
}
countDownLatch.countDown();
});
try {
countDownLatch.await();
} catch (InterruptedException e) {
log.error("中断异常:{}", e.getMessage());
e.printStackTrace();
}
executorService.shutdown();
System.out.println("count = " + count);
}
}
上面的程序含义是,跑两个线程任务task,每个线程任务都是对成员变量count进行1000次递增操作,最终的结果应该是2000,然而,经过多次运行,结果不一定都是2000,比如下面的这种结果。
为什么会出现count不等于2000,而是其它数值呢?因为count++不是一个原子操作,count++非原子操作,那么这就是我们需要使用原子操作类AtomicInteger的原因了。
当然有了,那就是使用锁进行临界区资源的锁定操作,我们可以synchronized关键字绑定在方法上,也可以基于ReentrantLock锁实例对象,对需要的临界区资源进行加减锁来达到资源互斥,数据同步的效果,当然了,这两部分内容都是很多的,这里就不一一详细说明了,后面,随着内容的加深,自己会单独来举例说明一下的。
(1)构造函数
//构建一个初始值为0的原子类
public AtomicInteger() {
}
(2)构造函数
//构建一个给定初始值数据的构造函数
public AtomicInteger(int initialValue) {
value = initialValue;
}
//获取当前值
public final int get() {
return value;
}
//返回增加1之前的数据
public final int getAndIncrement() {
return unsafe.getAndAddInt(this, valueOffset, 1);
}
//返回增加1之后的数据,即更新后的数据
public final int incrementAndGet() {
return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
}
//进行减一操作,获取减一后的数据
public final int decrementAndGet() {
return unsafe.getAndAddInt(this, valueOffset, -1) - 1;
}
//获取到减一之前的数据
public final int getAndDecrement() {
return unsafe.getAndAddInt(this, valueOffset, -1);
}
我们可以在类中看到成员变量value是有volatile关键字修饰的。volatile关键字修饰的内容,是可以保证内存可见性。