tokenpocket钱包苹果app官方下载|atomicinteger

作者: tokenpocket钱包苹果app官方下载
2024-03-09 23:06:47

Java AtomicInteger的用法 - 简书

AtomicInteger的用法 - 简书登录注册写文章首页下载APP会员IT技术Java AtomicInteger的用法java欧阳丰关注赞赏支持Java AtomicInteger的用法1、java.util.concurrent.atomic 的包里有AtomicBoolean, AtomicInteger,AtomicLong,AtomicLongArray,

AtomicReference等原子类的类,主要用于在高并发环境下的高效程序处理,来帮助我们简化同步处理.

在Java语言中,++i和i++操作并不是线程安全的,在使用的时候,不可避免的会用到synchronized关键字。而AtomicInteger则通过一种线程安全的加减操作接口。

2、AtomicInteger的基本方法

创建一个AtomicInteger

System.out.println(atomicInteger.get());

--->输出 : 123

创建一个不传值的,默认值为0

AtomicInteger atomicInteger = new AtomicInteger();

System.out.println(atomicInteger.get());

---->输出: 0

获取和赋值

atomicInteger.get(); //获取当前值

atomicInteger.set(999); //设置当前值

atomicInteger.compareAndSet(expectedValue,newValue)

public static void main(String[] args) {

AtomicInteger atomicInteger = new AtomicInteger(0);

System.out.println(atomicInteger.get());

int expectedValue = 123;

int newValue = 234;

Boolean b =atomicInteger.compareAndSet(expectedValue, newValue);

System.out.println(b);

System.out.println(atomicInteger);

}

----》输出结果为: 0 false 0

public static void main(String[] args) {

AtomicInteger atomicInteger = new AtomicInteger(123);

System.out.println(atomicInteger.get());

int expectedValue = 123;

int newValue = 234;

Boolean b =atomicInteger.compareAndSet(expectedValue, newValue);

System.out.println(b);

System.out.println(atomicInteger);

}

-----》输出结果为: 123 true 234

由上可知该方法表示,atomicInteger的值与expectedValue相比较,如果不相等,则返回false,

atomicInteger原有值保持不变;如果两者相等,则返回true,atomicInteger的值更新为newValue

getAndAdd()方法与AddAndGet方法

AtomicInteger atomicInteger = new AtomicInteger(123);

System.out.println(atomicInteger.get()); --123

System.out.println(atomicInteger.getAndAdd(10)); --123 获取当前值,并加10

System.out.println(atomicInteger.get()); --133

System.out.println(atomicInteger.addAndGet(10)); --143 获取加10后的值,先加10

System.out.println(atomicInteger.get()); --143

getAndDecrement()和DecrementAndGet()方法

AtomicInteger atomicInteger = new AtomicInteger(123);

System.out.println(atomicInteger.get()); --123

System.out.println(atomicInteger.getAndDecrement()); --123 获取当前值并自减

System.out.println(atomicInteger.get()); --122

System.out.println(atomicInteger.decrementAndGet()); --121 先自减再获取减1后的值

System.out.println(atomicInteger.get()); --121

3、使用AtomicInteger,即使不用同步块synchronized,最后的结果也是100,可用看出AtomicInteger的作用,用原子方式更新的int值。主要用于在高并发环境下的高效程序处理。使用非阻塞算法来实现并发控制。

public class Counter {

public static AtomicInteger count = new AtomicInteger(0);

public static void inc(){

try{

Thread.sleep(1); //延迟1毫秒

}catch (InterruptedException e){ //catch住中断异常,防止程序中断

e.printStackTrace();

}

count.getAndIncrement();//count值自加1

}

public static void main(String[] args) throws InterruptedException {

final CountDownLatch latch = new CountDownLatch(100);

for(int i=0;i<100;i++){

new Thread(new Runnable() {

@Override

public void run() {

Counter.inc();

latch.countDown();

}

}).start();

}

latch.await();

System.out.println("运行结果:"+Counter.count);

}

}

运行结果: 100

4、使用普通Integer

public class Counter {

public volatile static int count = 0;

public static void inc(){

try{

Thread.sleep(1); //延迟1毫秒

}catch (InterruptedException e){ //catch住中断异常,防止程序中断

e.printStackTrace();

}

count++;//count值自加1

}

public static void main(String[] args) throws InterruptedException {

final CountDownLatch latch = new CountDownLatch(100);

for(int i=0;i<100;i++){

new Thread(new Runnable() {

@Override

public void run() {

Counter.inc();

latch.countDown();

}

}).start();

}

latch.await();

System.out.println("运行结果:"+Counter.count);

}

}

运行结果:98

5、如果在inc方法前面加个synchronized也能是线程安全的;

它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。

import java.util.concurrent.CountDownLatch;

/**

* created by guanguan on 2017/10/23

**/

public class Counter {

public volatile static Integer count = 0;

public synchronized static void inc(){

try{

Thread.sleep(1); //延迟1毫秒

}catch (InterruptedException e){ //catch住中断异常,防止程序中断

e.printStackTrace();

}

count++;//count值自加1

}

public static void main(String[] args) throws InterruptedException {

final CountDownLatch latch = new CountDownLatch(100);

for(int i=0;i<100;i++){

new Thread(new Runnable() {

@Override

public void run() {

Counter.inc();

latch.countDown();

}

}).start();

}

latch.await();

System.out.println("运行结果:"+Counter.count);

}

}

运行结果:100

synchronized的使用说明:

一、当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。

二、然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。

三、尤其关键的是,当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。

四、第三个例子同样适用其它同步代码块。也就是说,当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁。结果,其它线程对该object对象所有同步代码部分的访问都被暂时阻塞。

五、以上规则对其它对象锁同样适用.

6、从上面的例子中我们可以看出:使用AtomicInteger是非常的安全的.而且因为AtomicInteger由硬件提供原子操作指令实现的。在非激烈竞争的情况下,开销更小,速度更快。

java的关键域有3个

// setup to use Unsafe.compareAndSwapInt for updates

private static final Unsafe unsafe = Unsafe.getUnsafe();

private static final long valueOffset;

private volatile int value;

这里, unsafe是java提供的获得对对象内存地址访问的类,注释已经清楚的写出了,它的作用就是在更新操作时提供“比较并替换”的作用。实际上就是AtomicInteger中的一个工具。

valueOffset是用来记录value本身在内存的便宜地址的,这个记录,也主要是为了在更新操作在内存中找到value的位置,方便比较。

注意:value是用来存储整数的时间变量,这里被声明为volatile,就是为了保证在更新操作时,当前线程可以拿到value最新的值(并发环境下,value可能已经被其他线程更新了)。

这里,我们以自增的代码为例,可以看到这个并发控制的核心算法:

源码

public final int updateAndGet(IntUnaryOperator updateFunction) {

int prev, next;

do {

prev = get();

next = updateFunction.applyAsInt(prev);

} while (!compareAndSet(prev, next));

return next;

}

©著作权归作者所有,转载或内容合作请联系作者 人面猴序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...沈念sama阅读 145,866评论 1赞 309死咒序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...沈念sama阅读 62,394评论 1赞 260救了他两次的神仙让他今天三更去死文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...开封第一讲书人阅读 96,852评论 0赞 214道士缉凶录:失踪的卖姜人 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...开封第一讲书人阅读 41,592评论 0赞 186港岛之恋(遗憾婚礼)正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...茶点故事阅读 49,465评论 1赞 263恶毒庶女顶嫁案:这布局不是一般人想出来的文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...开封第一讲书人阅读 39,091评论 1赞 180城市分裂传说那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...沈念sama阅读 30,669评论 2赞 279双鸳鸯连环套:你想象不到人心有多黑文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...开封第一讲书人阅读 29,435评论 0赞 172万荣杀人案实录序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...沈念sama阅读 32,820评论 0赞 217护林员之死正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...茶点故事阅读 29,534评论 2赞 221白月光启示录正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...茶点故事阅读 30,865评论 1赞 233活死人序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...沈念sama阅读 27,312评论 2赞 218日本核电站爆炸内幕正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...茶点故事阅读 31,810评论 3赞 214男人毒药:我在死后第九天来索命文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...开封第一讲书人阅读 25,703评论 0赞 9一桩弑父案,背后竟有这般阴谋文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...开封第一讲书人阅读 26,135评论 0赞 170情欲美人皮我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...沈念sama阅读 33,844评论 2赞 236代替公主和亲正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...茶点故事阅读 33,990评论 2赞 239推荐阅读更多精彩内容Java基础知识整理整理来自互联网 1,JDK:Java Development Kit,java的开发和运行环境,java的开发工具...Ncompass阅读 1,508评论 0赞 6java基础部分复习一:java概述: 1,JDK:Java Development Kit,java的开发和运行环境,java的开发...慕容小伟阅读 1,717评论 0赞 10Android 面试之 Java 篇三本文出自 Eddy Wiki ,转载请注明出处:http://eddy.wiki/interview-java.h...eddy_wiki阅读 1,873评论 0赞 14Java基础知识总结一:java概述:1,JDK:Java Development Kit,java的开发和运行环境,java的开发工...ZaneInTheSun阅读 2,574评论 0赞 11面试知识点1Java8张图 11、字符串不变性 12、equals()方法、hashCode()方法的区别 13、...Miley_MOJIE阅读 3,602评论 0赞 11评论0赞2020赞21赞赞赏更

AtomicInteger

AtomicInteger

JavaScript is disabled on your browser.

跳过导航

概述

模块

软件包

使用

已过时的

索引

帮助

Java SE 11 & JDK 11

所有类

SEARCH:

JavaScript is disabled on your browser.

概要: 

嵌套 | 

字段 | 

构造方法 | 

方法

详细信息: 

字段 | 

构造方法 | 

方法

 

模块 

java.base

软件包 

java.util.concurrent.atomic

Class AtomicInteger

java.lang.Object

java.lang.Number

java.util.concurrent.atomic.AtomicInteger

实现的所有接口

Serializable

public class AtomicInteger

extends Number

implements Serializable

可以原子方式更新的int值。

有关原子访问属性的描述,请参阅VarHandle规范。

AtomicInteger用于诸如原子递增计数器的应用程序中,并且不能用作Integer的替代品。

但是,此类确实扩展了Number以允许通过处理基于数字的类的工具和实用程序进行统一访问。

从以下版本开始:

1.5

另请参见:

Serialized Form

构造方法摘要

构造方法

 

构造器

描述

AtomicInteger()

创建一个初始值为

0的新AtomicInteger。

AtomicInteger​(int initialValue)

使用给定的初始值创建新的AtomicInteger。

方法摘要

所有方法 

实例方法

具体的方法 

弃用的方法 

变量和类型

方法

描述

int

accumulateAndGet​(int x, IntBinaryOperator accumulatorFunction)

原子更新(具有由

VarHandle.compareAndSet(java.lang.Object...)指定的记忆效应)当前值以及将给定函数应用于当前值和给定值的结果,返回更新的值。

int

addAndGet​(int delta)

原子地将给定值添加到当前值,具有由

VarHandle.getAndAdd(java.lang.Object...)指定的记忆效应。

int

compareAndExchange​(int expectedValue, int newValue)

原子将值设置为

newValue如果当前值,被称为

证人值 ,

== expectedValue如通过指定,记忆效应

VarHandle.compareAndExchange(java.lang.Object...) 。

int

compareAndExchangeAcquire​(int expectedValue, int newValue)

原子将值设置为

newValue如果当前值,被称为

证人值 ,

== expectedValue如通过指定,记忆效应

VarHandle.compareAndExchangeAcquire(java.lang.Object...) 。

int

compareAndExchangeRelease​(int expectedValue, int newValue)

原子将值设置为

newValue如果当前值,被称为

证人值 ,

== expectedValue如通过指定,记忆效应

VarHandle.compareAndExchangeRelease(java.lang.Object...) 。

boolean

compareAndSet​(int expectedValue, int newValue)

原子将值设置为

newValue如果当前值

== expectedValue如通过指定,记忆效应

VarHandle.compareAndSet(java.lang.Object...) 。

int

decrementAndGet()

原子地递减当前值,具有由

VarHandle.getAndAdd(java.lang.Object...)指定的记忆效应。

double

doubleValue()

返回此的当前值

AtomicInteger作为

double加宽原始转换后,通过规定的,具有记忆效果

VarHandle.getVolatile(java.lang.Object...) 。

float

floatValue()

在扩展基元转换后,将此

AtomicInteger的当前值返回为

float ,其内存效果由

VarHandle.getVolatile(java.lang.Object...)指定。

int

get()

返回当前值,具有

VarHandle.getVolatile(java.lang.Object...)指定的内存效果。

int

getAcquire()

返回当前值,具有

VarHandle.getAcquire(java.lang.Object...)指定的内存效果。

int

getAndAccumulate​(int x, IntBinaryOperator accumulatorFunction)

原子更新(具有由

VarHandle.compareAndSet(java.lang.Object...)指定的记忆效应)当前值以及将给定函数应用于当前值和给定值的结果,返回先前值。

int

getAndAdd​(int delta)

原子地将给定值添加到当前值,具有由

VarHandle.getAndAdd(java.lang.Object...)指定的记忆效应。

int

getAndDecrement()

原子地递减当前值,具有由

VarHandle.getAndAdd(java.lang.Object...)指定的记忆效应。

int

getAndIncrement()

以原子方式递增当前值,具有由

VarHandle.getAndAdd(java.lang.Object...)指定的记忆效应。

int

getAndSet​(int newValue)

以原子方式将值设置为

newValue并返回旧值,并使用

VarHandle.getAndSet(java.lang.Object...)指定的内存效果。

int

getAndUpdate​(IntUnaryOperator updateFunction)

原子更新(具有

VarHandle.compareAndSet(java.lang.Object...)指定的记忆效应)当前值和应用给定函数的结果,返回先前的值。

int

getOpaque()

返回当前值,具有

VarHandle.getOpaque(java.lang.Object...)指定的内存效果。

int

getPlain()

返回当前值,读取的内存语义就像变量声明为非

volatile 。

int

incrementAndGet()

以原子方式递增当前值,具有

VarHandle.getAndAdd(java.lang.Object...)指定的记忆效应。

int

intValue()

返回此的当前值

AtomicInteger作为

int如通过指定,记忆效应

VarHandle.getVolatile(java.lang.Object...) 。

void

lazySet​(int newValue)

将值设置为

newValue ,具有由

VarHandle.setRelease(java.lang.Object...)指定的内存效果。

long

longValue()

在扩展基元转换后,将此

AtomicInteger的当前值返回为

long ,其内存效果由

VarHandle.getVolatile(java.lang.Object...)指定。

void

set​(int newValue)

将值设置为

newValue ,具有

VarHandle.setVolatile(java.lang.Object...)指定的记忆效果。

void

setOpaque​(int newValue)

将值设置为

newValue ,具有

VarHandle.setOpaque(java.lang.Object...)指定的记忆效果。

void

setPlain​(int newValue)

将值设置为

newValue ,设置的内存语义就像变量声明为非

volatile和非

final 。

void

setRelease​(int newValue)

将值设置为

newValue ,具有

VarHandle.setRelease(java.lang.Object...)指定的记忆效果。

String

toString()

返回当前值的String表示形式。

int

updateAndGet​(IntUnaryOperator updateFunction)

原子更新(具有由

VarHandle.compareAndSet(java.lang.Object...)指定的记忆效应)当前值和应用给定函数的结果,返回更新的值。

boolean

weakCompareAndSet​(int expectedValue, int newValue)

已过时。

此方法具有简单的记忆效应,但方法名称意味着易失性记忆效应(请参阅compareAndExchange(int, int)和compareAndSet(int, int)等方法)。

boolean

weakCompareAndSetAcquire​(int expectedValue, int newValue)

可能原子将值设置为

newValue如果当前值

== expectedValue如通过指定,记忆效应

VarHandle.weakCompareAndSetAcquire(java.lang.Object...) 。

boolean

weakCompareAndSetPlain​(int expectedValue, int newValue)

可能原子将值设置为

newValue如果当前值

== expectedValue如通过指定,记忆效应

VarHandle.weakCompareAndSetPlain(java.lang.Object...) 。

boolean

weakCompareAndSetRelease​(int expectedValue, int newValue)

可能原子将值设置为

newValue如果当前值

== expectedValue如通过指定,记忆效应

VarHandle.weakCompareAndSetRelease(java.lang.Object...) 。

boolean

weakCompareAndSetVolatile​(int expectedValue, int newValue)

可能原子将值设置为

newValue如果当前值

== expectedValue如通过指定,记忆效应

VarHandle.weakCompareAndSet(java.lang.Object...) 。

声明方法的类 java.lang.Number byteValue, shortValue

声明方法的类 java.lang.Object clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait

构造方法详细信息

AtomicInteger public AtomicInteger​(int initialValue)

使用给定的初始值创建新的AtomicInteger。

参数

initialValue - 初始值

AtomicInteger public AtomicInteger()

创建一个初始值为

0的新AtomicInteger。

方法详细信息

get public final int get()

返回当前值,具有

VarHandle.getVolatile(java.lang.Object...)指定的内存效果。

结果

当前的价值

set public final void set​(int newValue)

将值设置为

newValue ,具有

VarHandle.setVolatile(java.lang.Object...)指定的记忆效果。

参数

newValue - 新值

lazySet public final void lazySet​(int newValue)

将值设置为

newValue ,具有

VarHandle.setRelease(java.lang.Object...)指定的记忆效果。

参数

newValue - 新值

从以下版本开始:

1.6

getAndSet public final int getAndSet​(int newValue)

以原子方式将值设置为

newValue并返回旧值,并使用

VarHandle.getAndSet(java.lang.Object...)指定的内存效果。

参数

newValue - 新值

结果

以前的值

compareAndSet public final boolean compareAndSet​(int expectedValue,

int newValue)

原子将值设置为

newValue如果当前值

== expectedValue如通过指定,记忆效应

VarHandle.compareAndSet(java.lang.Object...) 。

参数

expectedValue - 预期值

newValue - 新值

结果

true如果成功。

错误返回表示实际值不等于预期值。

weakCompareAndSet @Deprecated(since="9")

public final boolean weakCompareAndSet​(int expectedValue,

int newValue)

Deprecated.

This method has plain memory effects but the method name implies volatile memory effects (see methods such as

compareAndExchange(int, int) and

compareAndSet(int, int)). To avoid confusion over plain or volatile memory effects it is recommended that the method

weakCompareAndSetPlain(int, int) be used instead.

可能原子将值设置为

newValue如果当前值

== expectedValue如通过指定,记忆效应

VarHandle.weakCompareAndSetPlain(java.lang.Object...) 。

参数

expectedValue - 预期值

newValue - 新值

结果

true如果成功

另请参见:

weakCompareAndSetPlain(int, int)

weakCompareAndSetPlain public final boolean weakCompareAndSetPlain​(int expectedValue,

int newValue)

可能原子将值设置为

newValue如果当前值

== expectedValue如通过指定,记忆效应

VarHandle.weakCompareAndSetPlain(java.lang.Object...) 。

参数

expectedValue - 期望值

newValue - 新值

结果

true如果成功

从以下版本开始:

9

getAndIncrement public final int getAndIncrement()

以原子方式递增当前值,具有VarHandle.getAndAdd(java.lang.Object...)指定的记忆效应。

相当于getAndAdd(1) 。

结果

以前的值

getAndDecrement public final int getAndDecrement()

原子地递减当前值,具有由VarHandle.getAndAdd(java.lang.Object...)指定的记忆效应。

相当于getAndAdd(-1) 。

结果

以前的值

getAndAdd public final int getAndAdd​(int delta)

原子地将给定值添加到当前值,具有由

VarHandle.getAndAdd(java.lang.Object...)指定的记忆效应。

参数

delta - 要添加的值

结果

以前的值

incrementAndGet public final int incrementAndGet()

以原子方式递增当前值,具有VarHandle.getAndAdd(java.lang.Object...)指定的记忆效应。

相当于addAndGet(1) 。

结果

更新的值

decrementAndGet public final int decrementAndGet()

原子地递减当前值,具有由VarHandle.getAndAdd(java.lang.Object...)指定的记忆效应。

相当于addAndGet(-1) 。

结果

更新的值

addAndGet public final int addAndGet​(int delta)

原子地将给定值添加到当前值,具有由

VarHandle.getAndAdd(java.lang.Object...)指定的记忆效应。

参数

delta - 要添加的值

结果

更新的值

getAndUpdate public final int getAndUpdate​(IntUnaryOperator updateFunction)

原子更新(具有由VarHandle.compareAndSet(java.lang.Object...)指定的记忆效应)当前值和应用给定函数的结果,返回先前的值。

该函数应该是无副作用的,因为当尝试的更新由于线程之间的争用而失败时,它可能会被重新应用。

参数

updateFunction - 无副作用的功能

结果

以前的值

从以下版本开始:

1.8

updateAndGet public final int updateAndGet​(IntUnaryOperator updateFunction)

原子更新(具有由VarHandle.compareAndSet(java.lang.Object...)指定的记忆效应)当前值和应用给定函数的结果,返回更新的值。

该函数应该是无副作用的,因为当尝试的更新由于线程之间的争用而失败时,它可能会被重新应用。

参数

updateFunction - 无副作用的功能

结果

更新的值

从以下版本开始:

1.8

getAndAccumulate public final int getAndAccumulate​(int x,

IntBinaryOperator accumulatorFunction)

原子更新(具有由VarHandle.compareAndSet(java.lang.Object...)指定的记忆效应)当前值以及将给定函数应用于当前值和给定值的结果,返回先前值。

该函数应该是无副作用的,因为当尝试的更新由于线程之间的争用而失败时,它可能会被重新应用。

该函数应用当前值作为其第一个参数,并将给定更新作为第二个参数。

参数

x - 更新值

accumulatorFunction - 两个参数的无副作用函数

结果

以前的值

从以下版本开始:

1.8

accumulateAndGet public final int accumulateAndGet​(int x,

IntBinaryOperator accumulatorFunction)

原子更新(具有由VarHandle.compareAndSet(java.lang.Object...)指定的记忆效应)当前值以及将给定函数应用于当前值和给定值的结果,返回更新的值。

该函数应该是无副作用的,因为当尝试的更新由于线程之间的争用而失败时,它可能会被重新应用。

该函数应用当前值作为其第一个参数,并将给定更新作为第二个参数。

参数

x - 更新值

accumulatorFunction - 两个参数的无副作用函数

结果

更新的值

从以下版本开始:

1.8

toString public String toString()

返回当前值的String表示形式。

重写:

toString在类

Object

结果

当前值的String表示形式

intValue public int intValue()

返回此的当前值AtomicInteger作为int如通过指定,记忆效应VarHandle.getVolatile(java.lang.Object...) 。

相当于get() 。

Specified by:

intValue在类

Number

结果

转换为类型

int后此对象表示的数值。

longValue public long longValue()

返回此的当前值

AtomicInteger作为

long加宽原始转换后,通过规定的,具有记忆效果

VarHandle.getVolatile(java.lang.Object...) 。

Specified by:

longValue类

Number

结果

转换为类型

long后此对象表示的数值。

See The Java™ Language Specification:

5.1.2拓宽原始转换

floatValue public float floatValue()

在扩展基元转换后,将此

AtomicInteger的当前值返回为

float ,其内存效果由

VarHandle.getVolatile(java.lang.Object...)指定。

Specified by:

floatValue在类

Number

结果

转换为类型

float后此对象表示的数值。

See The Java™ Language Specification:

5.1.2拓宽原始转换

doubleValue public double doubleValue()

在扩展基元转换后,返回

AtomicInteger的当前值作为

double ,具有由

VarHandle.getVolatile(java.lang.Object...)指定的内存效果。

Specified by:

doubleValue在类

Number

结果

转换为类型

double后此对象表示的数值。

See The Java™ Language Specification:

5.1.2拓宽原始转换

getPlain public final int getPlain()

返回当前值,读取的内存语义就像变量声明为非

volatile 。

结果

价值

从以下版本开始:

9

setPlain public final void setPlain​(int newValue)

将值设置为

newValue ,设置的内存语义就像变量声明为非

volatile和非

final 。

参数

newValue - 新值

从以下版本开始:

9

getOpaque public final int getOpaque()

返回当前值,具有

VarHandle.getOpaque(java.lang.Object...)指定的内存效果。

结果

价值

从以下版本开始:

9

setOpaque public final void setOpaque​(int newValue)

将值设置为

newValue ,具有

VarHandle.setOpaque(java.lang.Object...)指定的记忆效果。

参数

newValue - 新值

从以下版本开始:

9

getAcquire public final int getAcquire()

返回当前值,具有

VarHandle.getAcquire(java.lang.Object...)指定的内存效果。

结果

价值

从以下版本开始:

9

setRelease public final void setRelease​(int newValue)

将值设置为

newValue ,具有

VarHandle.setRelease(java.lang.Object...)指定的记忆效果。

参数

newValue - 新值

从以下版本开始:

9

compareAndExchange public final int compareAndExchange​(int expectedValue,

int newValue)

原子将值设置为

newValue如果当前值,被称为

证人值 ,

== expectedValue如通过指定,记忆效应

VarHandle.compareAndExchange(java.lang.Object...) 。

参数

expectedValue - 预期值

newValue - 新值

结果

见证值,如果成功则与预期值相同

从以下版本开始:

9

compareAndExchangeAcquire public final int compareAndExchangeAcquire​(int expectedValue,

int newValue)

原子将值设置为

newValue如果当前值,被称为

证人值 ,

== expectedValue如通过指定,记忆效应

VarHandle.compareAndExchangeAcquire(java.lang.Object...) 。

参数

expectedValue - 预期值

newValue - 新值

结果

见证值,如果成功则与预期值相同

从以下版本开始:

9

compareAndExchangeRelease public final int compareAndExchangeRelease​(int expectedValue,

int newValue)

原子将值设置为

newValue如果当前值,被称为

证人值 ,

== expectedValue如通过指定,记忆效应

VarHandle.compareAndExchangeRelease(java.lang.Object...) 。

参数

expectedValue - 预期值

newValue - 新值

结果

见证值,如果成功则与预期值相同

从以下版本开始:

9

weakCompareAndSetVolatile public final boolean weakCompareAndSetVolatile​(int expectedValue,

int newValue)

可能原子将值设置为

newValue如果当前值

== expectedValue如通过指定,记忆效应

VarHandle.weakCompareAndSet(java.lang.Object...) 。

参数

expectedValue - 预期值

newValue - 新值

结果

true如果成功

从以下版本开始:

9

weakCompareAndSetAcquire public final boolean weakCompareAndSetAcquire​(int expectedValue,

int newValue)

可能原子将值设置为

newValue如果当前值

== expectedValue如通过指定,记忆效应

VarHandle.weakCompareAndSetAcquire(java.lang.Object...) 。

参数

expectedValue - 预期值

newValue - 新值

结果

true如果成功

从以下版本开始:

9

weakCompareAndSetRelease public final boolean weakCompareAndSetRelease​(int expectedValue,

int newValue)

可能原子将值设置为

newValue如果当前值

== expectedValue如通过指定,记忆效应

VarHandle.weakCompareAndSetRelease(java.lang.Object...) 。

参数

expectedValue - 预期值

newValue - 新值

结果

true如果成功

从以下版本开始:

9

跳过导航

概述

模块

软件包

使用

已过时的

索引

帮助

Java SE 11 & JDK 11

所有类

JavaScript is disabled on your browser.

概要: 

嵌套 | 

字段 | 

构造方法 | 

方法

详细信息: 

字段 | 

构造方法 | 

方法

Report a bug or suggest an enhancement For further API reference and developer documentation see the Java SE Documentation, which contains more detailed, developer-targeted descriptions with conceptual overviews, definitions of terms, workarounds, and working code examples. Java is a trademark or registered trademark of Oracle and/or its affiliates in the US and other countries. Copyright © 1993, 2018, Oracle and/or its affiliates, 500 Oracle Parkway, Redwood Shores, CA 94065 USA.All rights reserved. Use is subject to license terms and the documentation redistribution policy.

详解java并发原子类AtomicInteger(基于jdk1.8源码分析) - 知乎

详解java并发原子类AtomicInteger(基于jdk1.8源码分析) - 知乎首发于java架构师系列切换模式写文章登录/注册详解java并发原子类AtomicInteger(基于jdk1.8源码分析)一瓶小可乐java并发包里面的类一直是学习和面试的重点,这篇文章主要是对java并发包的其中一个类AtomicInteger的讲解。从为什么要出现AtomicInteger再到其底层原理来一个分析。一、从a++说起为什么使用AtomicInteger我们知道java并发机制中主要有三个特性需要我们去考虑,原子性、可见性和有序性。volatile关键字可以保证可见性和有序性却无法保证原子性。而这个AtomicInteger的作用就是为了保证原子性。我们先看一个例子。public class Test {

//一个变量a

private static volatile int a = 0;

public static void main(String[] args) {

Test test = new Test();

Thread[] threads = new Thread[5];

//定义5个线程,每个线程加10

for (int i = 0; i < 5; i++) {

threads[i] = new Thread(() -> {

try {

for (int j = 0; j < 10; j++) {

System.out.println(a++);

Thread.sleep(500);

}

} catch (Exception e) {

e.printStackTrace();

}

});

threads[i].start();

}

}

}在上面的这个例子中,我们定义了一个变量a。并且使用了5个线程分别去增加。为了保证可见性和有序性我们使用了volatile关键字对a进行修饰。在这里我们只测试原子性。如果我们第一次接触的话肯定会觉得5个线程,每个线程加10,最后结果一定是50呀。我们可以运行一边测试一波。很明显,可能跟你想象的不一样。为什么会出现这个问题呢?这是因为变量a虽然保证了可见性和有序性,但是缺没有保证原子性。其原因我们可以来分析一下。对于a++的操作,其实可以分解为3个步骤。(1)从主存中读取a的值(2)对a进行加1操作(3)把a重新刷新到主存这三个步骤在单线程中一点问题都没有,但是到了多线程就出现了问题了。比如说有的线程已经把a进行了加1操作,但是还没来得及重新刷入到主存,其他的线程就重新读取了旧值。因为才造成了错误。如何去解决呢?方法当然很多,但是为了和我们今天的主题对应上,很自然的联想到使用AtomicInteger。下面我们使用AtomicInteger重新来测试一遍:public class Test3 {

//使用AtomicInteger定义a

static AtomicInteger a = new AtomicInteger();

public static void main(String[] args) {

Test3 test = new Test3();

Thread[] threads = new Thread[5];

for (int i = 0; i < 5; i++) {

threads[i] = new Thread(() -> {

try {

for (int j = 0; j < 10; j++) {

//使用getAndIncrement函数进行自增操作

System.out.println(a.incrementAndGet());

Thread.sleep(500);

}

} catch (Exception e) {

e.printStackTrace();

}

});

threads[i].start();

}

}

}在上面的代码中我们使用了AtomicInteger来定义a,而且使用了AtomicInteger的函数incrementAndGet来对a进行自增操作。现在我们再来测试一遍。现在使用了AtomicInteger,不管你测试多少次,最后结果一定是50。为什么会出现这样的结果呢?AtomicInteger又是如何保证了这样的特性呢?下面我们就正式的开始揭开其面纱。二、原理分析上面的例子中我们只是调用了incrementAndGet函数来进行自增操作。其实AtomicInteger类为我们提供了很多函数。可以先使用一下。1、基本使用public class Test4 {

private static AtomicInteger atomicInteger = new AtomicInteger();

//1、获取当前值

public static void getCurrentValue(){}

//2、设置value值

public static void setValue(){}

//3、先获取旧值,然后设置新值

public static void getAndSet(){}

//4、先取得旧值,然后再进行自增

public static void getAndIncrement(){}

//5、先获取旧值,然后再减少

public static void getAndDecrement(){}

//6、先获取旧值,然后再加10

public static void getAndAdd(){}

//7、先加1.然后获取新值

public static void incrementAndGet(){}

//8、先减1,然后获取新值

public static void decrementAndGet(){} 、

//9、先增加,然后再获取新值

public static void addAndGet(){}

}最常用的方法就是这么几个。当然了还有很多其他的方法。对于上面几个函数,每一个函数的意思都已经列了出来。意思都很简单。下面我们就通过源码的角度分析一下AtomicInteger的真正原理。2、源码分析既然AtomicInteger使用了incrementAndGet函数,那我们就直接来看这个方法,对于其他的方法也是同样的道理。我们直接看源码,这里使用的是jdk1.8的版本,不同的版本会有出入。/**

* Atomically increments by one the current value.

* @return the updated value

*/

public final int incrementAndGet() {

return unsafe.getAndAddInt(this, valueOffset, 1) + 1;

}在这里我们会看到,底层使用的是unsafe的getAndAddInt方法。这里你可能有一个疑问了,这个unsafe是个什么鬼,而且还有一个valueOffset参数又是什么,想要看明白,我们从源码的开头开始看起。public class AtomicInteger extends Number implements java.io.Serializable {

private static final long serialVersionUID = 6214790243416807050L;

// setup to use Unsafe.compareAndSwapInt for updates

private static final Unsafe unsafe = Unsafe.getUnsafe();

private static final long valueOffset;

static {

try {

valueOffset = unsafe.objectFieldOffset

(AtomicInteger.class.getDeclaredField("value"));

} catch (Exception ex) { throw new Error(ex); }

}

private volatile int value;

//这里还有更多的代码没有列出

}开头在Unsafe的上面会发现,有一行注释叫做Unsafe.compareAndSwapInt。这又是什么?带着这些疑问我们开始一点一点揭开其面纱。(1)compareAndSwapInt的含义compareAndSwapInt又叫做CAS,如果你将来找工作,这个不清楚的话,基本上可以告别java这个方向了。CAS 即比较并替换,实现并发算法时常用到的一种技术。CAS操作包含三个操作数——内存位置、预期原值及新值。执行CAS操作的时候,将内存位置的值与预期原值比较,如果相匹配,那么处理器会自动将该位置值更新为新值,否则,处理器不做任何操作。我看过无数篇文章,对这个概念都是这样解释的,但是一开始看会一脸懵逼。我们使用一个例子来解释相信你会更加的清楚。比如说给你儿子订婚。你儿子就是内存位置,你原本以为你儿子是和杨贵妃在一起了,结果在订婚的时候发现儿子身边是西施。这时候该怎么办呢?你一气之下不做任何操作。如果儿子身边是你预想的杨贵妃,你一看很开心就给他们订婚了,也叫作执行操作。现在你应该明白了吧。对于CAS的解释我不准备长篇大论讲解。因为里面涉及到的知识点还是挺多的。在这里你理解了其含义就好。(2)Unsafe的含义在上面我们主要是讲解了CAS的含义,CAS修饰在Unsafe上面。那这个Unsafe是什么意思呢?Unsafe是位于sun.misc包下的一个类,Unsafe类使Java语言拥有了类似C语言指针一样操作内存空间的能力,这无疑也增加了程序发生相关指针问题的风险。在程序中过度、不正确使用Unsafe类会使得程序出错的概率变大,使得Java这种安全的语言变得不再“安全”,因此对Unsafe的使用一定要慎重。这里说一句题外话,在jdk1.9中,对Usafe进行了删除,所以因为这,那些基于Usafe开发的框架慢慢的都死掉了。在这里也就是说,Usafe再进行getAndAddInt的时候,首先是先加1,然后对底层对象的地址做出了更改。这个地址是什么呢?这就是涉及到我们的第三个疑问参数了。(3)valueOffset的含义这个valueOffset是long类型的,代表的含义就是对象的地址的偏移量。下面我们重新解释一下这行代码。unsafe.getAndAddInt(this, valueOffset, 1) + 1。这行代码的含义是,usafe通过getAndAddInt方法,对原先对象的地址进行了加1操作。现在应该明白了。我们return的时候,也是直接返回的最新的值。这一点我们对比另外一个方法incrementAndGet就能看出。 /**

* Atomically increments by one the current value.

*

* @return the previous value

*/

public final int getAndIncrement() {

return unsafe.getAndAddInt(this, valueOffset, 1);

}在这个方法的源代码中我们可以看到最后的+1操作没有了,也就是说,直接返回的是旧地址的值,然后再进行自增操作。如何去拿的地址的偏移量呢?是通过下面这个代码。 static {

try {

valueOffset = unsafe.objectFieldOffset

(AtomicInteger.class.getDeclaredField("value"));

} catch (Exception ex) { throw new Error(ex); }

}OK,到了这一步相信你已经知道了,usafe对a的值使用getAndAddInt方法进行了加1操作。然后返回最新的值。那么这个getAndAddInt方法是如何实现的呢?我们可以在进入看看: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机制来完成的增加操作,第一个参数var1表示的是当前对象,也就是a。第二个参数var2表示的是地址偏移量第三个参数var3表示的是我们要增加的值,这里表示为1对于AtomicInteger的原理就是这,主要是通过Usafe的方式来完成的。Usafe又是通过CAS机制来实现的,因此想要弄清整个原子系列的真正实现,就是要搞清楚CAS机制。不过我会在下一章节进行讲解。3、其他方法对于其他方法其实也是同样的道理,我们可以给出几个看看。 public final int getAndAdd(int delta) {

return unsafe.getAndAddInt(this, valueOffset, delta);

}

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 addAndGet(int delta) {

return unsafe.getAndAddInt(this, valueOffset, delta) + delta;

}我们可以看到底层基本上还是Usafe来实现的。Usafe又是经过CAS实现。三、总结对于jdk1.8的并发包来说,底层基本上就是通过Usafe和CAS机制来实现的。有好处也肯定有一个坏处。从好的方面来讲,就是上面AtomicInteger类可以保持其原子性。但是从坏的方面来看,Usafe因为直接操作的底层地址,肯定不是那么安全,而且CAS机制也伴随着大量的问题,比如说有名的ABA问题等等。关于CAS机制,我也会在后续的文章中专门讲解。大家可以先根据那个给儿子订婚的例子有一个基本的认识。今天的文章先写到这,感谢各位老铁的支持。编辑于 2020-01-13 19:42Java并发Java 编程​赞同 23​​8 条评论​分享​喜欢​收藏​申请转载​文章被以下专栏收录java架构师系列公众号:愚公要移山。技术路上多坎坷,我是愚公

Java原子操作AtomicInteger的用法 - 简书

原子操作AtomicInteger的用法 - 简书登录注册写文章首页下载APP会员IT技术Java原子操作AtomicInteger的用法_Justin关注赞赏支持Java原子操作AtomicInteger的用法前言:

JDK1.5之后的java.util.concurrent.atomic包里,多了一批原子处理类。AtomicBoolean、AtomicInteger、AtomicLong、AtomicReference。主要用于在高并发环境下的高效程序处理,来帮助我们简化同步处理.

AtomicInteger:

AtomicInteger,一个提供原子操作的Integer的类。在Java语言中,++i和i++操作并不是线程安全的,在使用的时候,不可避免的会用到synchronized关键字。而AtomicInteger则通过一种线程安全的加减操作接口。

我们先来看看AtomicInteger给我们提供了什么接口:

public final int get() //获取当前的值

public final int getAndSet(int newValue)//获取当前的值,并设置新的值

public final int getAndIncrement()//获取当前的值,并自增

public final int getAndDecrement() //获取当前的值,并自减

public final int getAndAdd(int delta) //获取当前的值,并加上预期的值

下面通过两个简单的例子来看一下 AtomicInteger 的优势在哪:

普通线程同步:

class Test2 {

private volatile int count = 0;

public synchronized void increment() {

count++; //若要线程安全执行执行count++,需要加锁

}

public int getCount() {

return count;

}

}

使用AtomicInteger:

class Test2 {

private AtomicInteger count = new AtomicInteger();

public void increment() {

count.incrementAndGet();

}

//使用AtomicInteger之后,不需要加锁,也可以实现线程安全。

public int getCount() {

return count.get();

}

}

从上面的例子中我们可以看出:使用AtomicInteger是非常的安全的.而且因为AtomicInteger由硬件提供原子操作指令实现的。在非激烈竞争的情况下,开销更小,速度更快。

我们来看看AtomicInteger是如何使用非阻塞算法来实现并发控制的:

AtomicInteger的关键域只有一下3个:

// setup to use Unsafe.compareAndSwapInt for updates

private static final Unsafe unsafe = Unsafe.getUnsafe();

private static final long valueOffset;

static {

try {

valueOffset = unsafe.objectFieldOffset (AtomicInteger.class.getDeclaredField("value"));

} catch (Exception ex) {

throw new Error(ex);

}

}

private volatile int value;

这里, unsafe是java提供的获得对对象内存地址访问的类,注释已经清楚的写出了,它的作用就是在更新操作时提供“比较并替换”的作用。实际上就是AtomicInteger中的一个工具。

valueOffset是用来记录value本身在内存的便宜地址的,这个记录,也主要是为了在更新操作在内存中找到value的位置,方便比较。

注意:value是用来存储整数的时间变量,这里被声明为volatile,就是为了保证在更新操作时,当前线程可以拿到value最新的值(并发环境下,value可能已经被其他线程更新了)。

这里,我们以自增的代码为例,可以看到这个并发控制的核心算法:

/**

*Atomicallyincrementsbyonethecurrentvalue.

*

*@returntheupdatedvalue

*/

publicfinalintincrementAndGet(){

for(;;){

//这里可以拿到value的最新值

intcurrent=get();

intnext=current+1;

if(compareAndSet(current,next))

returnnext;

}

}

publicfinalbooleancompareAndSet(intexpect,intupdate){

//使用unsafe的native方法,实现高效的硬件级别CAS

returnunsafe.compareAndSwapInt(this,valueOffset,expect,update);

}

优点总结:

最大的好处就是可以避免多线程的优先级倒置和死锁情况的发生,提升在高并发处理下的性能。

扩展链接:http://www.ibm.com/developerworks/cn/java/j-jtp11234/

最后编辑于 :2017.12.04 01:47:56©著作权归作者所有,转载或内容合作请联系作者人面猴序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...沈念sama阅读 145,866评论 1赞 309死咒序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...沈念sama阅读 62,394评论 1赞 260救了他两次的神仙让他今天三更去死文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...开封第一讲书人阅读 96,852评论 0赞 214道士缉凶录:失踪的卖姜人 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...开封第一讲书人阅读 41,592评论 0赞 186港岛之恋(遗憾婚礼)正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...茶点故事阅读 49,465评论 1赞 263恶毒庶女顶嫁案:这布局不是一般人想出来的文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...开封第一讲书人阅读 39,091评论 1赞 180城市分裂传说那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...沈念sama阅读 30,669评论 2赞 279双鸳鸯连环套:你想象不到人心有多黑文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...开封第一讲书人阅读 29,435评论 0赞 172万荣杀人案实录序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...沈念sama阅读 32,820评论 0赞 217护林员之死正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...茶点故事阅读 29,534评论 2赞 221白月光启示录正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...茶点故事阅读 30,865评论 1赞 233活死人序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...沈念sama阅读 27,312评论 2赞 218日本核电站爆炸内幕正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...茶点故事阅读 31,810评论 3赞 214男人毒药:我在死后第九天来索命文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...开封第一讲书人阅读 25,703评论 0赞 9一桩弑父案,背后竟有这般阴谋文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...开封第一讲书人阅读 26,135评论 0赞 170情欲美人皮我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...沈念sama阅读 33,844评论 2赞 236代替公主和亲正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...茶点故事阅读 33,990评论 2赞 239推荐阅读更多精彩内容Spring CloudSpring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...卡卡罗2017阅读 134,023评论 18赞 139Java初级面试题1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...子非鱼_t_阅读 31,252评论 18赞 399多线程知识梳理(1) - 并发编程的艺术笔记第三章 Java内存模型 3.1 Java内存模型的基础 通信在共享内存的模型里,通过写-读内存中的公共状态进行隐...泽毛阅读 4,267评论 2赞 222017-10-8姓名:马其岳 公司:宁波大发化纤有限公司 【日精进打卡第13天】 【知~学习】 《六项精进》大纲 2遍- 《大学》...马其岳阅读 173评论 0赞 0行走与安定 我在火车站等了两个多小时,一个人静静地坐着,看着人群涌动。 耗费了等待的感情,火车开动了。窗外是流动的风...西焕阅读 252评论 1赞 3评论2赞3030赞31赞赞赏更

AtomicInteger (Java Platform SE 8 )

AtomicInteger (Java Platform SE 8 )

JavaScript is disabled on your browser.

Skip navigation links

Overview

Package

Class

Use

Tree

Deprecated

Index

Help

Java™ PlatformStandard Ed. 8

Prev Class

Next Class

Frames

No Frames

All Classes

Summary: 

Nested | 

Field | 

Constr | 

Method

Detail: 

Field | 

Constr | 

Method

compact1, compact2, compact3

java.util.concurrent.atomic

Class AtomicInteger

java.lang.Object

java.lang.Number

java.util.concurrent.atomic.AtomicInteger

All Implemented Interfaces:

Serializable

public class AtomicInteger

extends Number

implements Serializable

An int value that may be updated atomically. See the

java.util.concurrent.atomic package specification for

description of the properties of atomic variables. An

AtomicInteger is used in applications such as atomically

incremented counters, and cannot be used as a replacement for an

Integer. However, this class does extend

Number to allow uniform access by tools and utilities that

deal with numerically-based classes.

Since:

1.5

See Also:

Serialized Form

Constructor Summary

Constructors 

Constructor and Description

AtomicInteger()

Creates a new AtomicInteger with initial value 0.

AtomicInteger(int initialValue)

Creates a new AtomicInteger with the given initial value.

Method Summary

All Methods Instance Methods Concrete Methods 

Modifier and Type

Method and Description

int

accumulateAndGet(int x,

IntBinaryOperator accumulatorFunction)

Atomically updates the current value with the results of

applying the given function to the current and given values,

returning the updated value.

int

addAndGet(int delta)

Atomically adds the given value to the current value.

boolean

compareAndSet(int expect,

int update)

Atomically sets the value to the given updated value

if the current value == the expected value.

int

decrementAndGet()

Atomically decrements by one the current value.

double

doubleValue()

Returns the value of this AtomicInteger as a double

after a widening primitive conversion.

float

floatValue()

Returns the value of this AtomicInteger as a float

after a widening primitive conversion.

int

get()

Gets the current value.

int

getAndAccumulate(int x,

IntBinaryOperator accumulatorFunction)

Atomically updates the current value with the results of

applying the given function to the current and given values,

returning the previous value.

int

getAndAdd(int delta)

Atomically adds the given value to the current value.

int

getAndDecrement()

Atomically decrements by one the current value.

int

getAndIncrement()

Atomically increments by one the current value.

int

getAndSet(int newValue)

Atomically sets to the given value and returns the old value.

int

getAndUpdate(IntUnaryOperator updateFunction)

Atomically updates the current value with the results of

applying the given function, returning the previous value.

int

incrementAndGet()

Atomically increments by one the current value.

int

intValue()

Returns the value of this AtomicInteger as an int.

void

lazySet(int newValue)

Eventually sets to the given value.

long

longValue()

Returns the value of this AtomicInteger as a long

after a widening primitive conversion.

void

set(int newValue)

Sets to the given value.

String

toString()

Returns the String representation of the current value.

int

updateAndGet(IntUnaryOperator updateFunction)

Atomically updates the current value with the results of

applying the given function, returning the updated value.

boolean

weakCompareAndSet(int expect,

int update)

Atomically sets the value to the given updated value

if the current value == the expected value.

Methods inherited from class java.lang.Number

byteValue, shortValue

Methods inherited from class java.lang.Object

clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait

Constructor Detail

AtomicInteger

public AtomicInteger(int initialValue)

Creates a new AtomicInteger with the given initial value.

Parameters:

initialValue - the initial value

AtomicInteger

public AtomicInteger()

Creates a new AtomicInteger with initial value 0.

Method Detail

get

public final int get()

Gets the current value.

Returns:

the current value

set

public final void set(int newValue)

Sets to the given value.

Parameters:

newValue - the new value

lazySet

public final void lazySet(int newValue)

Eventually sets to the given value.

Parameters:

newValue - the new value

Since:

1.6

getAndSet

public final int getAndSet(int newValue)

Atomically sets to the given value and returns the old value.

Parameters:

newValue - the new value

Returns:

the previous value

compareAndSet

public final boolean compareAndSet(int expect,

int update)

Atomically sets the value to the given updated value

if the current value == the expected value.

Parameters:

expect - the expected value

update - the new value

Returns:

true if successful. False return indicates that

the actual value was not equal to the expected value.

weakCompareAndSet

public final boolean weakCompareAndSet(int expect,

int update)

Atomically sets the value to the given updated value

if the current value == the expected value.

May fail

spuriously and does not provide ordering guarantees, so is

only rarely an appropriate alternative to compareAndSet.

Parameters:

expect - the expected value

update - the new value

Returns:

true if successful

getAndIncrement

public final int getAndIncrement()

Atomically increments by one the current value.

Returns:

the previous value

getAndDecrement

public final int getAndDecrement()

Atomically decrements by one the current value.

Returns:

the previous value

getAndAdd

public final int getAndAdd(int delta)

Atomically adds the given value to the current value.

Parameters:

delta - the value to add

Returns:

the previous value

incrementAndGet

public final int incrementAndGet()

Atomically increments by one the current value.

Returns:

the updated value

decrementAndGet

public final int decrementAndGet()

Atomically decrements by one the current value.

Returns:

the updated value

addAndGet

public final int addAndGet(int delta)

Atomically adds the given value to the current value.

Parameters:

delta - the value to add

Returns:

the updated value

getAndUpdate

public final int getAndUpdate(IntUnaryOperator updateFunction)

Atomically updates the current value with the results of

applying the given function, returning the previous value. The

function should be side-effect-free, since it may be re-applied

when attempted updates fail due to contention among threads.

Parameters:

updateFunction - a side-effect-free function

Returns:

the previous value

Since:

1.8

updateAndGet

public final int updateAndGet(IntUnaryOperator updateFunction)

Atomically updates the current value with the results of

applying the given function, returning the updated value. The

function should be side-effect-free, since it may be re-applied

when attempted updates fail due to contention among threads.

Parameters:

updateFunction - a side-effect-free function

Returns:

the updated value

Since:

1.8

getAndAccumulate

public final int getAndAccumulate(int x,

IntBinaryOperator accumulatorFunction)

Atomically updates the current value with the results of

applying the given function to the current and given values,

returning the previous value. The function should be

side-effect-free, since it may be re-applied when attempted

updates fail due to contention among threads. The function

is applied with the current value as its first argument,

and the given update as the second argument.

Parameters:

x - the update value

accumulatorFunction - a side-effect-free function of two arguments

Returns:

the previous value

Since:

1.8

accumulateAndGet

public final int accumulateAndGet(int x,

IntBinaryOperator accumulatorFunction)

Atomically updates the current value with the results of

applying the given function to the current and given values,

returning the updated value. The function should be

side-effect-free, since it may be re-applied when attempted

updates fail due to contention among threads. The function

is applied with the current value as its first argument,

and the given update as the second argument.

Parameters:

x - the update value

accumulatorFunction - a side-effect-free function of two arguments

Returns:

the updated value

Since:

1.8

toString

public String toString()

Returns the String representation of the current value.

Overrides:

toString in class Object

Returns:

the String representation of the current value

intValue

public int intValue()

Returns the value of this AtomicInteger as an int.

Specified by:

intValue in class Number

Returns:

the numeric value represented by this object after conversion

to type int.

longValue

public long longValue()

Returns the value of this AtomicInteger as a long

after a widening primitive conversion.

Specified by:

longValue in class Number

Returns:

the numeric value represented by this object after conversion

to type long.

See The Java™ Language Specification:

5.1.2 Widening Primitive Conversions

floatValue

public float floatValue()

Returns the value of this AtomicInteger as a float

after a widening primitive conversion.

Specified by:

floatValue in class Number

Returns:

the numeric value represented by this object after conversion

to type float.

See The Java™ Language Specification:

5.1.2 Widening Primitive Conversions

doubleValue

public double doubleValue()

Returns the value of this AtomicInteger as a double

after a widening primitive conversion.

Specified by:

doubleValue in class Number

Returns:

the numeric value represented by this object after conversion

to type double.

See The Java™ Language Specification:

5.1.2 Widening Primitive Conversions

Skip navigation links

Overview

Package

Class

Use

Tree

Deprecated

Index

Help

Java™ PlatformStandard Ed. 8

Prev Class

Next Class

Frames

No Frames

All Classes

Summary: 

Nested | 

Field | 

Constr | 

Method

Detail: 

Field | 

Constr | 

Method

Submit a bug or feature For further API reference and developer documentation, see Java SE Documentation. That documentation contains more detailed, developer-targeted descriptions, with conceptual overviews, definitions of terms, workarounds, and working code examples. Copyright © 1993, 2024, Oracle and/or its affiliates. All rights reserved. Use is subject to license terms. Also see the documentation redistribution policy.

Scripting on this page tracks web page traffic, but does not change the content in any way.

并发类 AtomicInteger 使用入门及源码详解 - 知乎

并发类 AtomicInteger 使用入门及源码详解 - 知乎切换模式写文章登录/注册并发类 AtomicInteger 使用入门及源码详解老马啸西风AtomicInterger 介绍可以原子性更新的 Integer 值,当然这个类并不能完全替代 Integer 对象。使用 使用起来还是很方便的。比如说我们定义一个计数器,使用 AtomicInteger 可以同时兼顾性能与并发安全。import java.util.concurrent.atomic.AtomicInteger;

/**

* @author binbin.hou

* @since 1.0.0

*/

public class Counter {

private AtomicInteger c = new AtomicInteger(0);

/**

* 递增

*/

public void increment() {

c.getAndIncrement();

}

/**

* 获取值

* @return 值

*/

public int value() {

return c.get();

}

public static void main(String[] args) throws InterruptedException {

final Counter counter = new Counter();

//1000 threads

for(int i = 0; i < 100 ; i++) {

new Thread(new Runnable() {

public void run() {

counter.increment();

}

}).start();

}

Thread.sleep(1000);

System.out.println("Final number (should be 100): " + counter.value());

}

}

日志输出:Final number (should be 100): 100

AtomicInteger 源码可恶!这个类使用起来竟然这么方便。那么李大狗是如何实现的呢?类定义 public class AtomicInteger extends Number implements java.io.Serializable {

private static final long serialVersionUID = 6214790243416807050L;

}

继承自 Number 类,实现了序列化接口。内部属性 这里初始化了 unsafe 变量,用于后面使用 CAS 做变量更新。// setup to use Unsafe.compareAndSwapInt for updates

private static final Unsafe unsafe = Unsafe.getUnsafe();

// 值的偏移量

private static final long valueOffset;

static {

try {

valueOffset = unsafe.objectFieldOffset

(AtomicInteger.class.getDeclaredField("value"));

} catch (Exception ex) { throw new Error(ex); }

}

// 定义的变量值

private volatile int value;

objectFieldOffset 方法这是一个 native 方法,换言之就是直接调用的操作系统,获取到 value 变量的内存偏移量信息。public native long objectFieldOffset(Field var1);

构造器 平淡无奇的构造器,用来初始化 value。当然也可以不指定,不指定的时候默认值是什么呢?我想各位读者肯定都清楚,不清楚的可以留言区忏悔一下。/**

* Creates a new AtomicInteger with the given initial value.

*

* @param initialValue the initial value

*/

public AtomicInteger(int initialValue) {

value = initialValue;

}

/**

* Creates a new AtomicInteger with initial value {@code 0}.

*/

public AtomicInteger() {

}

基本的方法 /**

* Gets the current value.

*

* @return the current value

*/

public final int get() {

return value;

}

/**

* Sets to the given value.

*

* @param newValue the new value

*/

public final void set(int newValue) {

value = newValue;

}

/**

* Returns the String representation of the current value.

* @return the String representation of the current value

*/

public String toString() {

return Integer.toString(get());

}

/**

* Returns the value of this {@code AtomicInteger} as an {@code int}.

*/

public int intValue() {

return get();

}

/**

* Returns the value of this {@code AtomicInteger} as a {@code long}

* after a widening primitive conversion.

* @jls 5.1.2 Widening Primitive Conversions

*/

public long longValue() {

return (long)get();

}

/**

* Returns the value of this {@code AtomicInteger} as a {@code float}

* after a widening primitive conversion.

* @jls 5.1.2 Widening Primitive Conversions

*/

public float floatValue() {

return (float)get();

}

/**

* Returns the value of this {@code AtomicInteger} as a {@code double}

* after a widening primitive conversion.

* @jls 5.1.2 Widening Primitive Conversions

*/

public double doubleValue() {

return (double)get();

}

这两个方法和普通类中的 getter/setter等并没有区别,此处不做过多解释。基于 unsafe 的方法 为什么 AtomicInteger 能保持原子性呢?我们一起来看一下是如何基于 Unsafe 实现原子性的?lazySet 惰性设置/**

* Eventually sets to the given value.

*

* @param newValue the new value

* @since 1.6

*/

public final void lazySet(int newValue) {

unsafe.putOrderedInt(this, valueOffset, newValue);

}

最终会把值设置为给定的值。这是什么意思?我直接懵了。其实这个是相对的,我们前面说过,volatile 修饰的变量,修改后可以保证线程间的可见性。但是这个方法,修改后并不保证线程间的可见性。这和以前在网上看到的可不一样,不是说好的 AtomicXXX 都是基于 volatile+cas 实现的吗?这里为什么要反其道而行之呢?其实是为了性能,lazySet 有自己的应用场景。高级程序员都知道 volatile 可以保证变量在线程间的可见性,但是这里再问一句,不使用 volatile 修饰就无法保证可见性了吗?事实上,这里完全可以不用 volatile 变量来修饰这些共享状态,因为访问共享状态之前先要获得锁, Lock.lock()方法能够获得锁,而获得锁的操作和volatile变量的读操作一样,会强制使CPU缓存失效,强制从内存读取变量。 Lock.unlock()方法释放锁时,和写volatile变量一样,会强制刷新CPU写缓冲区,把缓存数据写到主内存 底层也是通过加内存屏障实现的。而lazySet()优化原理,就是在不需要让共享变量的修改立刻让其他线程可见的时候,以设置普通变量的方式来修改共享状态,可以减少不必要的内存屏障,从而提高程序执行的效率。这个讨论可以参考 stackoverflow 的问题 AtomicInteger lazySet vs. set原子性设置值/**

* Atomically sets to the given value and returns the old value.

*

* @param newValue the new value

* @return the previous value

*/

public final int getAndSet(int newValue) {

return unsafe.getAndSetInt(this, valueOffset, newValue);

}

这个方法实现如下:public final int getAndSetInt(Object var1, long var2, int var4) {

int var5;

do {

var5 = this.getIntVolatile(var1, var2);

} while(!this.compareAndSwapInt(var1, var2, var5, var4));

return var5;

}

实际上就是我们常说的 volatile + CAS 实现。compareAndSet 比较并且设置jdk 将 CAS 这个方法暴露给了开发者,不过做了一层封装,让 unsafe 类对使用者不可见。compareAndSwapInt 这个方法是一个 native 方法,此处不做深入。其他的方法很多都大同小异,所以我们不再赘述。ps: 很烦,native 方法直接看源码就会变得很麻烦,以后有时间研究下 openJdk 之类的。/**

* Atomically sets the value to the given updated value

* if the current value {@code ==} the expected value.

*

* @param expect the expected value

* @param update the new value

* @return {@code true} if successful. False return indicates that

* the actual value was not equal to the expected value.

*/

public final boolean compareAndSet(int expect, int update) {

return unsafe.compareAndSwapInt(this, valueOffset, expect, update);

}

weakCompareAndSet这个方法我觉得也很有趣,弱比较?拿泥搜来。/**

* Atomically sets the value to the given updated value

* if the current value {@code ==} the expected value.

*

*

May fail

* spuriously and does not provide ordering guarantees, so is

* only rarely an appropriate alternative to {@code compareAndSet}.

*

* @param expect the expected value

* @param update the new value

* @return {@code true} if successful

*/

public final boolean weakCompareAndSet(int expect, int update) {

return unsafe.compareAndSwapInt(this, valueOffset, expect, update);

}

我们发现这两个方法在 jdk1.8 中实际上是没有差异的。底层调用的都是同一个方法:public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);

那区别是什么呢?于是我就去查了一下,JDK1.9以前,两者底层实现是一样的,并没有严格区分。JDK 1.9提供了Variable Handles的API,主要是用来取代java.util.concurrent.atomic包以及sun.misc.Unsafe类的功能。Variable Handles需要依赖jvm的增强及编译器的协助,即需要依赖java语言规范及jvm规范的升级。VarHandle中compareAndSet和compareAndSet的定义如下:(1)compareAndSet(Object... args)Atomically sets the value of a variable to the newValue with the memory semantics of set(java.lang.Object...) if the variable's current value, referred to as the witness value, == the expectedValue, as accessed with the memory semantics of getAcquire(java.lang.Object...).

(2)weakCompareAndSet(Object... args)Possibly atomically sets the value of a variable to the newValue with the memory semantics of setVolatile(java.lang.Object...) if the variable's current value, referred to as the witness value, == the expectedValue, as accessed with the memory semantics of getVolatile(java.lang.Object...).

weakCompareAndSet的描述多了一个单词Possibly,可能的。weakCompareAndSet有可能不是原子性的去更新值,这取决于虚拟机的实现。@HotSpotIntrinsicCandidate 标注的方法,在HotSpot中都有一套高效的实现,该高效实现基于CPU指令,运行时,HotSpot维护的高效实现会替代JDK的源码实现,从而获得更高的效率。也就是说HotSpot可能会手动实现这个方法。@PolymorphicSignature

@HotSpotIntrinsicCandidate

public final native boolean compareAndSet(Object... var1);

@PolymorphicSignature

@HotSpotIntrinsicCandidate

public final native boolean weakCompareAndSet(Object... var1);

其实这个方法和上面的 lazySet 有异曲同工之妙。小结我们对 AtomicInteger 源码进行了初步的分析,底层也确实是依赖 volatile+CAS 实现。不过发现了两个有趣的实现:weakCompareAndSet 和 lazySet。看起来反其道而行之,实际上都是出于更高的性能考虑。文中很多方法都是 native 实现,这让我们读起来不够尽兴,说到底这个世界上本没有高级语言,只有C语言,和对C语言的封装。希望本文对你有帮助,如果有其他想法的话,也可以评论区和大家分享哦。各位极客的点赞收藏转发,是老马写作的最大动力!发布于 2020-10-28 20:57static高并发面试问题​赞同​​添加评论​分享​喜欢​收藏​申请

AtomicInteger使用详解 - 简书

icInteger使用详解 - 简书登录注册写文章首页下载APP会员IT技术AtomicInteger使用详解因为我的心关注赞赏支持AtomicInteger使用详解一、什么是AtomicInteger

AtomicInteger类是系统底层保护的int类型,通过提供执行方法的控制进行值的原子操作。AtomicInteger它不能当作Integer来使用

从JAVA 1.5开始,AtomicInteger 属于java.util.concurrent.atomic 包下的一个类。

二、创建AtomicInteger 设置值获取值

AtomicInteger通过调用构造函数可以直接创建。在AtomicInteger提供了两种方法来获取和设置它的实例的值

//初始值是 0

AtomicInteger atomicInteger = new AtomicInteger();

//初始值是 100

AtomicInteger atomicInteger = new AtomicInteger(100);

int currentValue = atomicInteger.get(); //100

atomicInteger.set(1234); //当前值1234

三、什么情况下使用AtomicInteger

在现实生活中,我们需要AtomicInteger两种情况:

1、作为多个线程同时使用的原子计数器。

2、在比较和交换操作中实现非阻塞算法。

1、AtomicInteger作为原子计数器

要将它用作计数器,AtomicIntegerclass提供了一些以原子方式执行加法和减法操作的方法。

addAndGet()- 以原子方式将给定值添加到当前值,并在添加后返回新值。

getAndAdd() - 以原子方式将给定值添加到当前值并返回旧值。

incrementAndGet()- 以原子方式将当前值递增1并在递增后返回新值。它相当于i ++操作。

getAndIncrement() - 以原子方式递增当前值并返回旧值。它相当于++ i操作。

decrementAndGet()- 原子地将当前值减1并在减量后返回新值。它等同于i-操作。

getAndDecrement() - 以原子方式递减当前值并返回旧值。它相当于-i操作。

public class Main{

public static void main(String[] args)

{

AtomicInteger atomicInteger = new AtomicInteger(100);

System.out.println(atomicInteger.addAndGet(2)); //102

System.out.println(atomicInteger); //102

System.out.println(atomicInteger.getAndAdd(2)); //102

System.out.println(atomicInteger); //104

System.out.println(atomicInteger.incrementAndGet()); //105

System.out.println(atomicInteger); //105

System.out.println(atomicInteger.getAndIncrement()); //105

System.out.println(atomicInteger); //106

System.out.println(atomicInteger.decrementAndGet()); //105

System.out.println(atomicInteger); //105

System.out.println(atomicInteger.getAndDecrement()); //105

System.out.println(atomicInteger); //104

}

}

2、比较和交换操作

1、比较和交换操作将内存位置的内容与给定值进行比较,并且只有它们相同时,才将该内存位置的内容修改为给定的新值。这是作为单个原子操作完成的。

2、原子性保证了新值是根据最新信息计算出来的; 如果在此期间该值已被另一个线程更新,则写入将失败。

为了支持比较和交换操作,此类提供了一种方法,如果将该值原子地设置为给定的更新值current value == the expected value。

boolean compareAndSet(int expect, int update)

我们可以compareAndSet()在Java并发集合类中看到amy实时使用方法ConcurrentHashMap。

import java.util.concurrent.atomic.AtomicInteger;

public class Main{

public static void main(String[] args){

//1、默认初始值

AtomicInteger atomicInteger = new AtomicInteger(100);

//2、默认初始值和给定值,都是100,所以会更改成功

boolean isSuccess = atomicInteger.compareAndSet(100,110); //current value 100

//3、返回true

System.out.println(isSuccess); //true

//4、默认初始值是11,给定值是100,所以会更改失败

isSuccess = atomicInteger.compareAndSet(100,120); //current value 110

//5、返回false

System.out.println(isSuccess); //false

}

}

程序输出

true

false

四、总结

如上所述,主要用途AtomicInteger是当我们处于多线程上下文时,我们需要在不使用关键字的情况下对值执行原子操作。intsynchronized

AtomicInteger与使用同步执行相同操作相比,使用它同样更快,更易读。

参考:http://www.leftso.com/blog/568.html

最后编辑于 :2021.08.14 11:46:20©著作权归作者所有,转载或内容合作请联系作者人面猴序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...沈念sama阅读 145,866评论 1赞 309死咒序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...沈念sama阅读 62,394评论 1赞 260救了他两次的神仙让他今天三更去死文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...开封第一讲书人阅读 96,852评论 0赞 214道士缉凶录:失踪的卖姜人 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...开封第一讲书人阅读 41,592评论 0赞 186港岛之恋(遗憾婚礼)正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...茶点故事阅读 49,465评论 1赞 263恶毒庶女顶嫁案:这布局不是一般人想出来的文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...开封第一讲书人阅读 39,091评论 1赞 180城市分裂传说那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...沈念sama阅读 30,669评论 2赞 279双鸳鸯连环套:你想象不到人心有多黑文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...开封第一讲书人阅读 29,435评论 0赞 172万荣杀人案实录序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...沈念sama阅读 32,820评论 0赞 217护林员之死正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...茶点故事阅读 29,534评论 2赞 221白月光启示录正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...茶点故事阅读 30,865评论 1赞 233活死人序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...沈念sama阅读 27,312评论 2赞 218日本核电站爆炸内幕正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...茶点故事阅读 31,810评论 3赞 214男人毒药:我在死后第九天来索命文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...开封第一讲书人阅读 25,703评论 0赞 9一桩弑父案,背后竟有这般阴谋文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...开封第一讲书人阅读 26,135评论 0赞 170情欲美人皮我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...沈念sama阅读 33,844评论 2赞 236代替公主和亲正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...茶点故事阅读 33,990评论 2赞 239推荐阅读更多精彩内容Java并发AtomicInteger的使用AtomicInteger 类底层存储一个int值,并提供方法对该int值进行原子操作。AtomicInteger...小狐憨憨阅读 1,128评论 0赞 0Java AtomicInteger 使用指南AtomicInteger类通过提供对值执行原子操作的方法来保护基础的int值。 它不能代替Integer类。 从...程序员网址导航阅读 10,461评论 1赞 3java并发编程JUC第十二篇:AtomicInteger原子整型AtomicInteger 类底层存储一个int值,并提供方法对该int值进行原子操作。AtomicInteger...字母哥课堂阅读 192评论 0赞 1Zookeeper客户端Curator使用详解原文地址:https://www.jianshu.com/p/70151fc0ef5d Zookeeper客户端C...cn_yaojin阅读 749评论 0赞 0JUC框架&多线程5 Volatile 关键字 保证内存可见和有序向性,但是不保证原子性 虽然synchronized,jvm对它做...任笙_8b8c阅读 656评论 0赞 1评论0赞44赞5赞赞赏更

【Java原理系列】Java AtomicInteger原理用法源码详解 - 知乎

【Java原理系列】Java AtomicInteger原理用法源码详解 - 知乎首发于java jdk源码原理用法示例切换模式写文章登录/注册【Java原理系列】Java AtomicInteger原理用法源码详解SparkML​​东北大学 控制理论与控制工程硕士基本原理Java 中的 AtomicInteger 是一个原子类,用于实现对整数类型的原子操作。它提供了一系列方法,如 get()、set()、incrementAndGet()、compareAndSet() 等,可以在多线程环境下安全地进行原子操作。通过使用 AtomicInteger,可以避免使用显式的锁来保护共享整数变量,从而提高并发性能。它适用于许多并发场景,如计数器、标记位等。AtomicInteger 的原理基于 CAS(Compare-And-Swap)操作。它内部使用了 Unsafe 类或者其他底层的原子操作机制来实现线程安全的操作。通过 CAS 操作,AtomicInteger 可以保证在多线程环境下对整数值的修改是原子性的,避免了竞态条件和数据不一致等问题。AtomicInteger 的主要特点和原理如下: 1. 内部使用 volatile 修饰的 int 变量:AtomicInteger 内部有一个被 volatile 修饰的 int 变量,用于存储整数值。volatile 关键字确保了变量的可见性,使得对该变量的读写操作具有原子性。 2. 使用 CAS 操作进行原子更新:AtomicInteger 中的原子操作方法都是基于 CAS 操作实现的。CAS 操作包括比较内存中的值与预期值是否相等,如果相等则更新为新值,否则操作失败。CAS 操作利用底层硬件提供的原子指令,确保操作的原子性。 3. 循环重试:由于 CAS 操作可能在多线程环境下失败,因此 AtomicInteger 在实现中使用了循环重试的机制。如果 CAS 操作失败,它会不断尝试进行 CAS 操作,直到成功为止。注意事项AtomicInteger 并不能完全替代 Integer 类,因为它并没有提供自动装箱和拆箱的功能。 虽然 AtomicInteger 提供了原子操作,但仍然需要根据具体情况考虑原子类的使用范围和正确性。有时候,可能需要额外的同步手段来保证一些复合操作的原子性。 假设需要对一个计数器进行原子递增和条件检查,以决定是否执行某个操作。以下是一个示例代码:if (counter.incrementAndGet() >= threshold) {

// 执行操作

}尽管递增操作和条件检查各自都是原子的,但由于两个操作之间存在竞态条件,可能会导致结果不一致。因为在判断条件后,其他线程可能已经对计数器进行了修改。在这种情况下,可以使用额外的同步手段,如锁(synchronized)或者显示的使用 Lock 接口,来保证多个操作的原子性,可以确保递增操作、条件检查和操作的执行之间是原子的,避免了竞态条件。synchronized (lock) {

if (counter.incrementAndGet() >= threshold) {

// 执行操作

}

}基本方法以下是对 AtomicInteger 类中提供的方法进行总结:AtomicInteger(int initialValue):使用给定的初始值创建一个新的 AtomicInteger 对象。 AtomicInteger():创建一个新的 AtomicInteger 对象,并将初始值设为 0。 int get():获取当前存储的整数值。 void set(int newValue):设置整数值为指定的新值。 void lazySet(int newValue):最终将整数值设置为指定的新值。不保证立即生效,可能会延迟。 int getAndSet(int newValue):将整数值设置为指定的新值,并返回先前的值。 boolean compareAndSet(int expect, int update):如果当前值等于预期值,则原子地将整数值设置为指定的新值,并返回操作是否成功。 boolean weakCompareAndSet(int expect, int update):与 compareAndSet() 方法类似,但不提供强有力的保证和排序保证。 int getAndIncrement():先返回当前值,然后将整数值增加 1。 int getAndDecrement():先返回当前值,然后将整数值减少 1。 int getAndAdd(int delta):先返回当前值,然后将整数值增加指定的增量。 int incrementAndGet():将整数值增加 1,然后返回更新后的值。 int decrementAndGet():将整数值减少 1,然后返回更新后的值。 int addAndGet(int delta):将整数值增加指定的增量,然后返回更新后的值。 int getAndUpdate(IntUnaryOperator updateFunction):先获取当前值,然后将整数值更新为通过应用给定函数得到的新值,返回先前的值。 int updateAndGet(IntUnaryOperator updateFunction):先获取当前值,然后将整数值更新为通过应用给定函数得到的新值,返回更新后的值。 int getAndAccumulate(int x, IntBinaryOperator accumulatorFunction):先获取当前值,然后将整数值与给定值通过应用给定函数进行累积计算,返回先前的值。 int accumulateAndGet(int x, IntBinaryOperator accumulatorFunction):先获取当前值,然后将整数值与给定值通过应用给定函数进行累积计算,返回更新后的值。 String toString():以字符串形式返回当前存储的整数值。 int intValue():将当前存储的整数值转换为 int 类型并返回。 long longValue():将当前存储的整数值转换为 long 类型并返回。 float floatValue():将当前存储的整数值转换为 float 类型并返回。 double doubleValue():将当前存储的整数值转换为 double 类型并返回。 这些方法允许原子地对整数值进行各种操作,确保在多线程环境下的线程安全性。场景示例以下是几个适用场景和示例:计数器(Counter):AtomicInteger 可以用作计数器,在多线程环境下实现原子的自增、自减操作。例如,统计网站访问次数或任务完成数量等。public class Counter {

private AtomicInteger count = new AtomicInteger(0);

public void increment() {

count.incrementAndGet();

}

public void decrement() {

count.decrementAndGet();

}

public int getCount() {

return count.get();

}

}并发任务处理:在并发任务处理中,可以使用 AtomicInteger 来控制任务的执行顺序或限制同时执行的任务数量。import java.util.concurrent.atomic.AtomicInteger;

public class TaskProcessor {

private static final int MAX_CONCURRENT_TASKS = 10;

private AtomicInteger activeTasks = new AtomicInteger(0);

public void processTask(Runnable task) {

// 检查是否达到最大并发任务数

while (activeTasks.get() >= MAX_CONCURRENT_TASKS) {

// 等待其他任务完成后再继续执行

Thread.yield();

}

try {

activeTasks.incrementAndGet(); // 增加活动任务数

task.run(); // 执行任务

} finally {

activeTasks.decrementAndGet(); // 减少活动任务数

}

}

}线程安全的共享变量:当多个线程需要共享某个变量时,可以使用 AtomicInteger 来保证线程安全。例如,在多个线程中对共享计数器进行递增操作。import java.util.concurrent.atomic.AtomicInteger;

public class SharedVariableExample {

private static AtomicInteger counter = new AtomicInteger(0);

public static void main(String[] args) throws InterruptedException {

Runnable task = () -> {

for (int i = 0; i < 1000; i++) {

counter.incrementAndGet(); // 原子递增操作

}

};

Thread thread1 = new Thread(task);

Thread thread2 = new Thread(task);

thread1.start();

thread2.start();

thread1.join();

thread2.join();

System.out.println("Counter value: " + counter.get());

}

}在上述示例中,两个线程并发地对 counter 进行递增操作,通过 AtomicInteger 来保证递增操作的原子性,并最终输出正确的计数器值。总之,AtomicInteger 适用于多线程环境下对整数进行原子操作的场景,如计数器、并发任务处理和线程安全的共享变量等。它提供了一种高效且线程安全的方式来处理整数操作。中文源码/**

* 一个可以原子更新的 {@code int} 值。请参阅 {@link java.util.concurrent.atomic} 包规范,了解原子变量的属性描述。

* {@code AtomicInteger} 在诸如原子递增计数器等应用中使用,不能用作 {@link java.lang.Integer} 的替代品。

* 但是,该类扩展了 {@code Number} 类,以便允许工具和实用程序对基于数字的类进行统一访问。

*

* @since 1.5

* @author Doug Lea

*/

public class AtomicInteger extends Number implements java.io.Serializable {

private static final long serialVersionUID = 6214790243416807050L;

// 设置使用 Unsafe.compareAndSwapInt 进行更新

private static final Unsafe unsafe = Unsafe.getUnsafe();

private static final long valueOffset;

static {

try {

valueOffset = unsafe.objectFieldOffset(AtomicInteger.class.getDeclaredField("value"));

} catch (Exception ex) {

throw new Error(ex);

}

}

private volatile int value; // 使用 volatile 修饰,保证可见性

/**

* 使用给定的初始值创建一个新的 {@code AtomicInteger}。

*

* @param initialValue 初始值

*/

public AtomicInteger(int initialValue) {

value = initialValue; // 初始化整数值

}

/**

* 创建一个初始值为 {@code 0} 的新 {@code AtomicInteger}。

*/

public AtomicInteger() {

}

/**

* 获取当前值。

*

* @return 当前值

*/

public final int get() {

return value; // 获取当前存储的整数值

}

/**

* 设置为给定值。

*

* @param newValue 新值

*/

public final void set(int newValue) {

value = newValue; // 设置整数值为指定的新值

}

/**

* 最终设置为给定值。

*

* @param newValue 新值

* @since 1.6

*/

public final void lazySet(int newValue) {

unsafe.putOrderedInt(this, valueOffset, newValue); // 最终设置整数值为指定的新值,可能会延迟生效

}

/**

* 原子地设置为给定值,并返回旧值。

*

* @param newValue 新值

* @return 先前的值

*/

public final int getAndSet(int newValue) {

return unsafe.getAndSetInt(this, valueOffset, newValue); // 原子地设置整数值为指定的新值,并返回先前的值

}

/**

* 如果当前值 {@code ==} 预期值,则原子地将值设置为给定更新值。

*

* @param expect 预期值

* @param update 新值

* @return {@code true} 表示成功。返回 {@code false} 表示实际值不等于预期值。

*/

public final boolean compareAndSet(int expect, int update) {

return unsafe.compareAndSwapInt(this, valueOffset, expect, update); // 如果当前值等于预期值,则原子地将整数值设置为指定的新值,并返回操作是否成功

}

/**

* 如果当前值 {@code ==} 预期值,则原子地将值设置为给定更新值。

*

*

可能会出现虚假失败,不提供排序保证

* 因此很少作为 {@code compareAndSet} 的替代方法。

*

* @param expect 预期值

* @param update 新值

* @return {@code true} 表示成功

*/

public final boolean weakCompareAndSet(int expect, int update) {

return unsafe.compareAndSwapInt(this, valueOffset, expect, update); // 弱 CAS 操作,不提供强有力的保证和排序保证

}

/**

* 原子地将当前值加 1。

*

* @return 先前的值

*/

public final int getAndIncrement() {

return unsafe.getAndAddInt(this, valueOffset, 1); // 先返回当前值,然后将整数值增加 1

}

/**

* 原子地将当前值减 1。

*

* @return 先前的值

*/

public final int getAndDecrement() {

return unsafe.getAndAddInt(this, valueOffset, -1); // 先返回当前值,然后将整数值减少 1

}

/**

* 原子地将给定值加到当前值。

*

* @param delta 要添加的值

* @return 先前的值

*/

public final int getAndAdd(int delta) {

return unsafe.getAndAddInt(this, valueOffset, delta); // 先返回当前值,然后将整数值增加指定的增量

}

/**

* 原子地将当前值加 1。

*

* @return 更新后的值

*/

public final int incrementAndGet() {

return unsafe.getAndAddInt(this, valueOffset, 1) + 1; // 将整数值增加 1,然后返回更新后的值

}

/**

* 原子地将当前值减 1。

*

* @return 更新后的值

*/

public final int decrementAndGet() {

return unsafe.getAndAddInt(this, valueOffset, -1) - 1; // 将整数值减少 1,然后返回更新后的值

}

/**

* 原子地将给定值添加到当前值。

*

* @param delta 要添加的值

* @return 更新后的值

*/

public final int addAndGet(int delta) {

return unsafe.getAndAddInt(this, valueOffset, delta) + delta; // 将整数值增加指定的增量,然后返回更新后的值

}

/**

* 使用给定函数原子地更新当前值,并返回先前的值。由于可能在线程之间产生争用时重新应用尝试更新,

* 因此该函数应是无副作用的。

*

* @param updateFunction 无副作用的函数

* @return 先前的值

* @since 1.8

*/

public final int getAndUpdate(IntUnaryOperator updateFunction) {

int prev, next;

do {

prev = get();

next = updateFunction.applyAsInt(prev);

} while (!compareAndSet(prev, next));

return prev;

}

/**

* 使用给定函数原子地更新当前值,并返回更新后的值。由于可能在线程之间产生争用时重新应用尝试更新,

* 因此该函数应是无副作用的。

*

* @param updateFunction 无副作用的函数

* @return 更新后的值

* @since 1.8

*/

public final int updateAndGet(IntUnaryOperator updateFunction) {

int prev, next;

do {

prev = get();

next = updateFunction.applyAsInt(prev);

} while (!compareAndSet(prev, next));

return next;

}

/**

* 使用给定函数将当前值和给定值原子地更新,并返回先前的值。由于可能在线程之间产生争用时重新应用尝试更新,

* 因此该函数应是无副作用的。该函数将当前值作为第一个参数,给定更新作为第二个参数应用。

*

* @param x 更新值

* @param accumulatorFunction 两个参数的无副作用函数

* @return 先前的值

* @since 1.8

*/

public final int getAndAccumulate(int x,

IntBinaryOperator accumulatorFunction) {

int prev, next;

do {

prev = get();

next = accumulatorFunction.applyAsInt(prev, x);

} while (!compareAndSet(prev, next));

return prev;

}

/**

* 使用给定函数将当前值和给定值原子地更新,并返回更新后的值。由于可能在线程之间产生争用时重新应用尝试更新,

* 因此该函数应是无副作用的。该函数将当前值作为第一个参数,给定更新作为第二个参数应用。

*

* @param x 更新值

* @param accumulatorFunction 两个参数的无副作用函数

* @return 更新后的值

* @since 1.8

*/

public final int accumulateAndGet(int x,

IntBinaryOperator accumulatorFunction) {

int prev, next;

do {

prev = get();

next = accumulatorFunction.applyAsInt(prev, x);

} while (!compareAndSet(prev, next));

return next;

}

/**

* 返回当前值的字符串表示形式。

*

* @return 当前值的字符串表示形式

*/

public String toString() {

return Integer.toString(get());

}

/**

* 将此 {@code AtomicInteger} 的值作为 {@code int} 返回。

*/

public int intValue() {

return get();

}

/**

* 将此 {@code AtomicInteger} 的值作为 {@code long} 返回,进行扩展原始转换。

* @jls 5.1.2 扩展原始类型转换

*/

public long longValue() {

return (long)get();

}

/**

* 将此 {@code AtomicInteger} 的值作为 {@code float} 返回,进行扩展原始转换。

* @jls 5.1.2 扩展原始类型转换

*/

public float floatValue() {

return (float)get();

}

/**

* 将此 {@code AtomicInteger} 的值作为 {@code double} 返回,进行扩展原始转换。

* @jls 5.1.2 扩展原始类型转换

*/

public double doubleValue() {

return (double)get();

}

}官方链接编辑于 2024-01-29 14:31・IP 属地北京Java 编程Java​赞同​​添加评论​分享​喜欢​收藏​申请转载​文章被以下专栏收录java jdk源码原理用法示例让天下没有难理解的jav

AtomicInteger 中文文档 - Java教程,Java中文文档,最容易理解的Java中文文档

AtomicInteger 中文文档 - Java教程,Java中文文档,最容易理解的Java中文文档

您的浏览器禁用了 JavaScript。

   

跳过导航链接

Java SE 20 & JDK 20

概述

模块

使用

预览

新的

已弃用

索引

帮助

概括:

嵌套

Field

常量

Method

细节:

Field

常量

Method

概括:

嵌套 |

字段 |

常量  | 

方法

细节:

字段 |

常量  | 

方法

SEARCH

模块 java.base

包 java.util.concurrent.atomic

类 AtomicInteger

java.lang.Object

java.lang.Number

java.util.concurrent.atomic.AtomicInteger

所有已实现的接口:

Serializable

public class AtomicInteger extends Number implements Serializable

可以自动更新的 int 值。有关原子访问属性的描述,请参阅 VarHandle 规范。 AtomicInteger 用于原子递增计数器等应用,不能用作 Integer 的替代品。但是,此类确实扩展了 Number 以允许处理基于数字的类的工具和实用程序进行统一访问。

自从:

1.5

参见:

Serialized Form

构造方法总结

构造方法

构造方法

描述

AtomicInteger()

创建一个初始值为 0 的新 AtomicInteger。

AtomicInteger(int initialValue)

创建具有给定初始值的新 AtomicInteger。

方法总结

所有方法实例方法具体方法弃用的方法

修饰符和类型

方法

描述

final int

accumulateAndGet(int x, IntBinaryOperator accumulatorFunction)

以原子方式更新(具有 VarHandle.compareAndSet(java.lang.Object...) 指定的记忆效应)当前值以及将给定函数应用于当前值和给定值的结果,并返回更新后的值。

final int

addAndGet(int delta)

以原子方式将给定值添加到当前值,具有 VarHandle.getAndAdd(java.lang.Object...) 指定的记忆效应。

final int

compareAndExchange(int expectedValue, int newValue)

如果当前值称为 witness value、== expectedValue,具有 VarHandle.compareAndExchange(java.lang.Object...) 指定的记忆效应,则原子地将值设置为 newValue。

final int

compareAndExchangeAcquire(int expectedValue, int newValue)

如果当前值称为 witness value、== expectedValue,具有 VarHandle.compareAndExchangeAcquire(java.lang.Object...) 指定的记忆效应,则原子地将值设置为 newValue。

final int

compareAndExchangeRelease(int expectedValue, int newValue)

如果当前值称为 witness value、== expectedValue,具有 VarHandle.compareAndExchangeRelease(java.lang.Object...) 指定的记忆效应,则原子地将值设置为 newValue。

final boolean

compareAndSet(int expectedValue, int newValue)

如果当前值为 == expectedValue,则以原子方式将值设置为 newValue,并具有由 VarHandle.compareAndSet(java.lang.Object...) 指定的记忆效应。

final int

decrementAndGet()

以原子方式递减当前值,具有 VarHandle.getAndAdd(java.lang.Object...) 指定的记忆效应。

double

doubleValue()

在扩大基元转换后返回此 AtomicInteger 的当前值作为 double,具有 VarHandle.getVolatile(java.lang.Object...) 指定的记忆效应。

float

floatValue()

在扩大基元转换后返回此 AtomicInteger 的当前值作为 float,具有 VarHandle.getVolatile(java.lang.Object...) 指定的记忆效应。

final int

get()

返回当前值,具有 VarHandle.getVolatile(java.lang.Object...) 指定的记忆效应。

final int

getAcquire()

返回当前值,具有 VarHandle.getAcquire(java.lang.Object...) 指定的记忆效应。

final int

getAndAccumulate(int x, IntBinaryOperator accumulatorFunction)

以原子方式更新(具有 VarHandle.compareAndSet(java.lang.Object...) 指定的记忆效应)当前值以及将给定函数应用于当前值和给定值的结果,并返回先前的值。

final int

getAndAdd(int delta)

以原子方式将给定值添加到当前值,具有 VarHandle.getAndAdd(java.lang.Object...) 指定的记忆效应。

final int

getAndDecrement()

以原子方式递减当前值,具有 VarHandle.getAndAdd(java.lang.Object...) 指定的记忆效应。

final int

getAndIncrement()

以原子方式递增当前值,具有 VarHandle.getAndAdd(java.lang.Object...) 指定的记忆效应。

final int

getAndSet(int newValue)

以原子方式将值设置为 newValue 并返回旧值,具有 VarHandle.getAndSet(java.lang.Object...) 指定的记忆效应。

final int

getAndUpdate(IntUnaryOperator updateFunction)

以原子方式更新(具有 VarHandle.compareAndSet(java.lang.Object...) 指定的记忆效应)当前值与应用给定函数的结果,返回先前的值。

final int

getOpaque()

返回当前值,具有 VarHandle.getOpaque(java.lang.Object...) 指定的记忆效应。

final int

getPlain()

返回当前值,具有读取的内存语义,就好像变量被声明为 non-volatile 一样。

final int

incrementAndGet()

以原子方式递增当前值,具有 VarHandle.getAndAdd(java.lang.Object...) 指定的记忆效应。

int

intValue()

将此 AtomicInteger 的当前值作为 int 返回,具有由 VarHandle.getVolatile(java.lang.Object...) 指定的记忆效应。

final void

lazySet(int newValue)

将值设置为 newValue ,具有 VarHandle.setRelease(java.lang.Object...) 指定的记忆效应。

long

longValue()

在扩大基元转换后返回此 AtomicInteger 的当前值作为 long,具有 VarHandle.getVolatile(java.lang.Object...) 指定的记忆效应。

final void

set(int newValue)

将值设置为 newValue ,具有 VarHandle.setVolatile(java.lang.Object...) 指定的记忆效应。

final void

setOpaque(int newValue)

将值设置为 newValue ,具有 VarHandle.setOpaque(java.lang.Object...) 指定的记忆效应。

final void

setPlain(int newValue)

将值设置为 newValue ,设置的内存语义就好像变量被声明为 non-volatile 和 non-final 一样。

final void

setRelease(int newValue)

将值设置为 newValue ,具有 VarHandle.setRelease(java.lang.Object...) 指定的记忆效应。

String

toString()

返回当前值的字符串表示形式。

final int

updateAndGet(IntUnaryOperator updateFunction)

使用给定函数的应用结果以原子方式更新(具有 VarHandle.compareAndSet(java.lang.Object...) 指定的记忆效应)当前值,返回更新后的值。

final boolean

weakCompareAndSet(int expectedValue, int newValue)

已弃用。

此方法具有简单的记忆效应,但方法名称暗示易失性记忆效应(请参阅 compareAndExchange(int, int) 和 compareAndSet(int, int) 等方法)。

final boolean

weakCompareAndSetAcquire(int expectedValue, int newValue)

如果当前值为 == expectedValue,则可能自动将该值设置为 newValue,具有由 VarHandle.weakCompareAndSetAcquire(java.lang.Object...) 指定的记忆效应。

final boolean

weakCompareAndSetPlain(int expectedValue, int newValue)

如果当前值为 == expectedValue,则可能自动将该值设置为 newValue,并具有由 VarHandle.weakCompareAndSetPlain(java.lang.Object...) 指定的记忆效应。

final boolean

weakCompareAndSetRelease(int expectedValue, int newValue)

如果当前值为 == expectedValue,则可能自动将该值设置为 newValue,并具有由 VarHandle.weakCompareAndSetRelease(java.lang.Object...) 指定的记忆效应。

final boolean

weakCompareAndSetVolatile(int expectedValue, int newValue)

如果当前值为 == expectedValue,则可能自动将该值设置为 newValue,并具有由 VarHandle.weakCompareAndSet(java.lang.Object...) 指定的记忆效应。

在类 java.lang.Number 中声明的方法byteValue, shortValue

在类 java.lang.Object 中声明的方法clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait

构造方法详细信息

AtomicInteger

public AtomicInteger(int initialValue)

创建具有给定初始值的新 AtomicInteger。

参数:

initialValue - 初始值

AtomicInteger

public AtomicInteger()

创建一个初始值为 0 的新 AtomicInteger。

方法详情

get

public final int get()

返回当前值,具有 VarHandle.getVolatile(java.lang.Object...) 指定的记忆效应。

返回:

当前值

set

public final void set(int newValue)

将值设置为 newValue ,具有 VarHandle.setVolatile(java.lang.Object...) 指定的记忆效应。

参数:

newValue - 新值

lazySet

public final void lazySet(int newValue)

将值设置为 newValue ,具有 VarHandle.setRelease(java.lang.Object...) 指定的记忆效应。

参数:

newValue - 新值

自从:

1.6

getAndSet

public final int getAndSet(int newValue)

以原子方式将值设置为 newValue 并返回旧值,具有 VarHandle.getAndSet(java.lang.Object...) 指定的记忆效应。

参数:

newValue - 新值

返回:

以前的值

compareAndSet

public final boolean compareAndSet(int expectedValue, int newValue)

如果当前值为 == expectedValue,则以原子方式将值设置为 newValue,并具有由 VarHandle.compareAndSet(java.lang.Object...) 指定的记忆效应。

参数:

expectedValue - 期望值

newValue - 新值

返回:

true 如果成功。错误返回表示实际值不等于预期值。

weakCompareAndSet

@Deprecated (since ="9") public final boolean weakCompareAndSet(int expectedValue, int newValue)

已弃用。

此方法具有简单的记忆效应,但方法名称暗示易失性记忆效应(请参阅 compareAndExchange(int, int) 和 compareAndSet(int, int) 等方法)。为避免混淆普通或易失性记忆效应,建议改用方法 weakCompareAndSetPlain(int, int) 。

如果当前值为 == expectedValue,则可能自动将该值设置为 newValue,并具有由 VarHandle.weakCompareAndSetPlain(java.lang.Object...) 指定的记忆效应。

参数:

expectedValue - 期望值

newValue - 新值

返回:

true 如果成功

参见:

weakCompareAndSetPlain(int, int)

weakCompareAndSetPlain

public final boolean weakCompareAndSetPlain(int expectedValue, int newValue)

如果当前值为 == expectedValue,则可能自动将该值设置为 newValue,并具有由 VarHandle.weakCompareAndSetPlain(java.lang.Object...) 指定的记忆效应。

参数:

expectedValue - 期望值

newValue - 新值

返回:

true 如果成功

自从:

9

getAndIncrement

public final int getAndIncrement()

以原子方式递增当前值,具有 VarHandle.getAndAdd(java.lang.Object...) 指定的记忆效应。

相当于 getAndAdd(1) 。

返回:

以前的值

getAndDecrement

public final int getAndDecrement()

以原子方式递减当前值,具有 VarHandle.getAndAdd(java.lang.Object...) 指定的记忆效应。

相当于 getAndAdd(-1) 。

返回:

以前的值

getAndAdd

public final int getAndAdd(int delta)

以原子方式将给定值添加到当前值,具有 VarHandle.getAndAdd(java.lang.Object...) 指定的记忆效应。

参数:

delta - 要添加的值

返回:

以前的值

incrementAndGet

public final int incrementAndGet()

以原子方式递增当前值,具有 VarHandle.getAndAdd(java.lang.Object...) 指定的记忆效应。

相当于 addAndGet(1) 。

返回:

更新值

decrementAndGet

public final int decrementAndGet()

以原子方式递减当前值,具有 VarHandle.getAndAdd(java.lang.Object...) 指定的记忆效应。

相当于 addAndGet(-1) 。

返回:

更新值

addAndGet

public final int addAndGet(int delta)

以原子方式将给定值添加到当前值,具有 VarHandle.getAndAdd(java.lang.Object...) 指定的记忆效应。

参数:

delta - 要添加的值

返回:

更新值

getAndUpdate

public final int getAndUpdate(IntUnaryOperator  updateFunction)

以原子方式更新(具有 VarHandle.compareAndSet(java.lang.Object...) 指定的记忆效应)当前值与应用给定函数的结果,返回先前的值。该函数应该是无副作用的,因为当由于线程之间的争用而尝试更新失败时,它可能会被重新应用。

参数:

updateFunction - 无副作用的函数

返回:

以前的值

自从:

1.8

updateAndGet

public final int updateAndGet(IntUnaryOperator  updateFunction)

使用给定函数的应用结果以原子方式更新(具有 VarHandle.compareAndSet(java.lang.Object...) 指定的记忆效应)当前值,返回更新后的值。该函数应该是无副作用的,因为当由于线程之间的争用而尝试更新失败时,它可能会被重新应用。

参数:

updateFunction - 无副作用的函数

返回:

更新值

自从:

1.8

getAndAccumulate

public final int getAndAccumulate(int x, IntBinaryOperator  accumulatorFunction)

以原子方式更新(具有 VarHandle.compareAndSet(java.lang.Object...) 指定的记忆效应)当前值以及将给定函数应用于当前值和给定值的结果,并返回先前的值。该函数应该是无副作用的,因为当由于线程之间的争用而尝试更新失败时,它可能会被重新应用。该函数应用当前值作为其第一个参数,给定的更新作为第二个参数。

参数:

x - 更新值

accumulatorFunction - 两个参数的无副作用函数

返回:

以前的值

自从:

1.8

accumulateAndGet

public final int accumulateAndGet(int x, IntBinaryOperator  accumulatorFunction)

以原子方式更新(具有 VarHandle.compareAndSet(java.lang.Object...) 指定的记忆效应)当前值以及将给定函数应用于当前值和给定值的结果,并返回更新后的值。该函数应该是无副作用的,因为当由于线程之间的争用而尝试更新失败时,它可能会被重新应用。该函数应用当前值作为其第一个参数,给定的更新作为第二个参数。

参数:

x - 更新值

accumulatorFunction - 两个参数的无副作用函数

返回:

更新值

自从:

1.8

toString

public String  toString()

返回当前值的字符串表示形式。

重写:

toString 在类 Object 中

返回:

当前值的 String 表示形式

intValue

public int intValue()

将此 AtomicInteger 的当前值作为 int 返回,具有由 VarHandle.getVolatile(java.lang.Object...) 指定的记忆效应。相当于 get() 。

指定者:

intValue 在类 Number 中

返回:

转换为类型 int 后此对象表示的数值。

longValue

public long longValue()

在扩大基元转换后返回此 AtomicInteger 的当前值作为 long,具有 VarHandle.getVolatile(java.lang.Object...) 指定的记忆效应。

指定者:

longValue 在类 Number 中

返回:

转换为类型 long 后此对象表示的数值。

看Java 语言规范:

5.1.2 拓宽原始转换

floatValue

public float floatValue()

在扩大基元转换后返回此 AtomicInteger 的当前值作为 float,具有 VarHandle.getVolatile(java.lang.Object...) 指定的记忆效应。

指定者:

floatValue 在类 Number 中

返回:

转换为类型 float 后此对象表示的数值。

看Java 语言规范:

5.1.2 拓宽原始转换

doubleValue

public double doubleValue()

在扩大基元转换后返回此 AtomicInteger 的当前值作为 double,具有 VarHandle.getVolatile(java.lang.Object...) 指定的记忆效应。

指定者:

doubleValue 在类 Number 中

返回:

转换为类型 double 后此对象表示的数值。

看Java 语言规范:

5.1.2 拓宽原始转换

getPlain

public final int getPlain()

返回当前值,具有读取的内存语义,就好像变量被声明为 non-volatile 一样。

返回:

自从:

9

setPlain

public final void setPlain(int newValue)

将值设置为 newValue ,设置的内存语义就好像变量被声明为 non-volatile 和 non-final 一样。

参数:

newValue - 新值

自从:

9

getOpaque

public final int getOpaque()

返回当前值,具有 VarHandle.getOpaque(java.lang.Object...) 指定的记忆效应。

返回:

自从:

9

setOpaque

public final void setOpaque(int newValue)

将值设置为 newValue ,具有 VarHandle.setOpaque(java.lang.Object...) 指定的记忆效应。

参数:

newValue - 新值

自从:

9

getAcquire

public final int getAcquire()

返回当前值,具有 VarHandle.getAcquire(java.lang.Object...) 指定的记忆效应。

返回:

自从:

9

setRelease

public final void setRelease(int newValue)

将值设置为 newValue ,具有 VarHandle.setRelease(java.lang.Object...) 指定的记忆效应。

参数:

newValue - 新值

自从:

9

compareAndExchange

public final int compareAndExchange(int expectedValue, int newValue)

如果当前值称为 witness value、== expectedValue,具有 VarHandle.compareAndExchange(java.lang.Object...) 指定的记忆效应,则原子地将值设置为 newValue。

参数:

expectedValue - 期望值

newValue - 新值

返回:

见证值,如果成功,它将与预期值相同

自从:

9

compareAndExchangeAcquire

public final int compareAndExchangeAcquire(int expectedValue, int newValue)

如果当前值称为 witness value、== expectedValue,具有 VarHandle.compareAndExchangeAcquire(java.lang.Object...) 指定的记忆效应,则原子地将值设置为 newValue。

参数:

expectedValue - 期望值

newValue - 新值

返回:

见证值,如果成功,它将与预期值相同

自从:

9

compareAndExchangeRelease

public final int compareAndExchangeRelease(int expectedValue, int newValue)

如果当前值称为 witness value、== expectedValue,具有 VarHandle.compareAndExchangeRelease(java.lang.Object...) 指定的记忆效应,则原子地将值设置为 newValue。

参数:

expectedValue - 期望值

newValue - 新值

返回:

见证值,如果成功,它将与预期值相同

自从:

9

weakCompareAndSetVolatile

public final boolean weakCompareAndSetVolatile(int expectedValue, int newValue)

如果当前值为 == expectedValue,则可能自动将该值设置为 newValue,并具有由 VarHandle.weakCompareAndSet(java.lang.Object...) 指定的记忆效应。

参数:

expectedValue - 期望值

newValue - 新值

返回:

true 如果成功

自从:

9

weakCompareAndSetAcquire

public final boolean weakCompareAndSetAcquire(int expectedValue, int newValue)

如果当前值为 == expectedValue,则可能自动将该值设置为 newValue,具有由 VarHandle.weakCompareAndSetAcquire(java.lang.Object...) 指定的记忆效应。

参数:

expectedValue - 期望值

newValue - 新值

返回:

true 如果成功

自从:

9

weakCompareAndSetRelease

public final boolean weakCompareAndSetRelease(int expectedValue, int newValue)

如果当前值为 == expectedValue,则可能自动将该值设置为 newValue,并具有由 VarHandle.weakCompareAndSetRelease(java.lang.Object...) 指定的记忆效应。

参数:

expectedValue - 期望值

newValue - 新值

返回:

true 如果成功

自从:

9

全栈行动派|全栈工具箱|联系我们

如需进一步的 API 参考和开发人员文档,请参阅 Java SE 文档,其中包含更详细的、以开发人员为目标的描述以及概念概述、术语定义、解决方法和工作代码示例。 其他版本。

Java 是 Oracle 和/或其附属公司在美国和其他国家/地区的商标或注册商标。版权 © 1993, 2023, Oracle 和/或其附属公司,500 Oracle Parkway, Redwood Shores, CA 94065 USA。

版权所有。使用受 许可条款 和 文件再分配策略 约束。

原子操作类AtomicInteger详解-CSDN博客

>

原子操作类AtomicInteger详解-CSDN博客

原子操作类AtomicInteger详解

最新推荐文章于 2024-03-08 15:53:10 发布

WD技术

最新推荐文章于 2024-03-08 15:53:10 发布

阅读量710

收藏

18

点赞数

16

分类专栏:

工作中遇到的问题

文章标签:

java

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/qq_44761854/article/details/136530512

版权

工作中遇到的问题

专栏收录该内容

51 篇文章

0 订阅

订阅专栏

为什么需要AtomicInteger原子操作类? 对于Java中的运算操作,例如自增或自减,若没有进行额外的同步操作,在多线程环境下就是线程不安全的。num++解析为num=num+1,明显,这个操作不具备原子性,多线程并发共享这个变量时必然会出现问题。测试代码如下:

public class AtomicIntegerTest {

private static final int THREADS_CONUT = 20;

public static int count = 0;

public static void increase() {

count++;

}

public static void main(String[] args) {

Thread[] threads = new Thread[THREADS_CONUT];

for (int i = 0; i < THREADS_CONUT; i++) {

threads[i] = new Thread(new Runnable() {

@Override

public void run() {

for (int i = 0; i < 1000; i++) {

increase();

}

}

});

threads[i].start();

}

while (Thread.activeCount() > 1) {

Thread.yield();

}

System.out.println(count);

}

}

这里运行了20个线程,每个线程对count变量进行1000此自增操作,如果上面这段代码能够正常并发的话,最后的结果应该是20000才对,但实际结果却发现每次运行的结果都不相同,都是一个小于20000的数字。这是为什么呢?

要是换成volatile修饰count变量呢? 顺带说下volatile关键字很重要的两个特性:

1、保证变量在线程间可见,对volatile变量所有的写操作都能立即反应到其他线程中,换句话说,volatile变量在各个线程中是一致的(得益于java内存模型—“先行发生原则”);

2、禁止指令的重排序优化;

那么换成volatile修饰count变量后,会有什么效果呢? 试一试:

public class AtomicIntegerTest {

private static final int THREADS_CONUT = 20;

public static volatile int count = 0;

public static void increase() {

count++;

}

public static void main(String[] args) {

Thread[] threads = new Thread[THREADS_CONUT];

for (int i = 0; i < THREADS_CONUT; i++) {

threads[i] = new Thread(new Runnable() {

@Override

public void run() {

for (int i = 0; i < 1000; i++) {

increase();

}

}

});

threads[i].start();

}

while (Thread.activeCount() > 1) {

Thread.yield();

}

System.out.println(count);

}

}

结果似乎又失望了,测试结果和上面的一致,每次都是输出小于20000的数字。这又是为什么么? 上面的论据是正确的,也就是上面标红的内容,但是这个论据并不能得出"基于volatile变量的运算在并发下是安全的"这个结论,因为核心点在于java里的运算(比如自增)并不是原子性的。

用了AtomicInteger类后会变成什么样子呢? 把上面的代码改造成AtomicInteger原子类型,先看看效果

import java.util.concurrent.atomic.AtomicInteger;

public class AtomicIntegerTest {

private static final int THREADS_CONUT = 20;

public static AtomicInteger count = new AtomicInteger(0);

public static void increase() {

count.incrementAndGet();

}

public static void main(String[] args) {

Thread[] threads = new Thread[THREADS_CONUT];

for (int i = 0; i < THREADS_CONUT; i++) {

threads[i] = new Thread(new Runnable() {

@Override

public void run() {

for (int i = 0; i < 1000; i++) {

increase();

}

}

});

threads[i].start();

}

while (Thread.activeCount() > 1) {

Thread.yield();

}

System.out.println(count);

}

}

结果每次都输出20000,程序输出了正确的结果,这都归功于AtomicInteger.incrementAndGet()方法的原子性。

非阻塞同步 同步:多线程并发访问共享数据时,保证共享数据再同一时刻只被一个或一些线程使用。

我们知道,阻塞同步和非阻塞同步都是实现线程安全的两个保障手段,非阻塞同步对于阻塞同步而言主要解决了阻塞同步中线程阻塞和唤醒带来的性能问题,那什么叫做非阻塞同步呢?在并发环境下,某个线程对共享变量先进行操作,如果没有其他线程争用共享数据那操作就成功;如果存在数据的争用冲突,那就才去补偿措施,比如不断的重试机制,直到成功为止,因为这种乐观的并发策略不需要把线程挂起,也就把这种同步操作称为非阻塞同步(操作和冲突检测具备原子性)。在硬件指令集的发展驱动下,使得 “操作和冲突检测” 这种看起来需要多次操作的行为只需要一条处理器指令便可以完成,这些指令中就包括非常著名的CAS指令(Compare-And-Swap比较并交换)。《深入理解Java虚拟机第二版.周志明》第十三章中这样描述关于CAS机制: 所以再返回来看AtomicInteger.incrementAndGet()方法,它的时间也比较简单

/**

* Atomically increments by one the current value.

*

* @return the updated value

*/

public final int incrementAndGet() {

for (;;) {

int current = get();

int next = current + 1;

if (compareAndSet(current, next))

return next;

}

}

incrementAndGet()方法在一个无限循环体内,不断尝试将一个比当前值大1的新值赋给自己,如果失败则说明在执行"获取-设置"操作的时已经被其它线程修改过了,于是便再次进入循环下一次操作,直到成功为止。这个便是AtomicInteger原子性的"诀窍"了,继续进源码看它的compareAndSet方法:

/**

* Atomically sets the value to the given updated value

* if the current value {@code ==} the expected value.

*

* @param expect the expected value

* @param update the new value

* @return true if successful. False return indicates that

* the actual value was not equal to the expected value.

*/

public final boolean compareAndSet(int expect, int update) {

return unsafe.compareAndSwapInt(this, valueOffset, expect, update);

}

可以看到,compareAndSet()调用的就是Unsafe.compareAndSwapInt()方法,即Unsafe类的CAS操作。

优惠劵

WD技术

关注

关注

16

点赞

18

收藏

觉得还不错?

一键收藏

打赏

知道了

0

评论

原子操作类AtomicInteger详解

上面的论据是正确的,也就是上面标红的内容,但是这个论据并不能得出"基于volatile变量的运算在并发下是安全的"这个结论,因为核心点在于java里的运算(比如自增)并不是原子性的。这里运行了20个线程,每个线程对count变量进行1000此自增操作,如果上面这段代码能够正常并发的话,最后的结果应该是20000才对,但实际结果却发现每次运行的结果都不相同,都是一个小于20000的数字。对于Java中的运算操作,例如自增或自减,若没有进行额外的同步操作,在多线程环境下就是线程不安全的。

复制链接

扫一扫

专栏目录

详解C++11原子类型与原子操作

12-17

1.认识原子操作 原子操作就是在多线程程序中“最小的且不可并行化的”操作,意味着多个线程访问同一个资源时,有且仅有一个线程能对资源进行操作。通常情况下原子操作可以通过互斥的访问方式来保证,例如Linux下的...

Android文件操作工具类详解

01-03

本文实例为大家分享了Android文件操作工具类的具体代码,供大家参考,具体内容如下 贴上我写的一个文件操作工具类,基本上覆盖了各种文件操作: 1、文件的新建、删除; 2、文件的复制; 3、获取文件扩展名; 4、文件...

参与评论

您还未登录,请先

登录

后发表或查看评论

java并发之原子操作类和非阻塞算法

08-26

主要为大家详细介绍了java并发之原子操作类和非阻塞算法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

MongoDB 原子操作

12-16

MongoDB 原子操作 mongodb不支持事务,所以,在你的项目中应用时,要注意这点。无论什么设计,都不要要求mongodb保证数据的完整性。 但是mongodb提供了许多原子操作,比如文档的保存,修改,删除等,都是原子操作。 ...

Asp.Net中Cache操作类实例详解

01-02

本文以一个Asp.Net的Cache操作类实例代码来详细描述了cache缓存的结构及实现方法,完整代码如下所示: /// /// /// 存储类(存储UserInfo信息) /// /// /// 用Cache存储用户信息 /// 在指定间隔...

重学SpringBoot3-yaml文件配置

CoderJia的学习之路

03-05

1127

YAML 提供了一种更为人性化的配置文件格式,它通过简洁的结构化格式,使得配置信息更加易于理解和维护。在 Spring Boot 中,通过使用 YAML,开发者可以轻松地管理和切换不同环境下的配置,优化开发流程。掌握 YAML 的基本写法和在 Spring Boot 中的应用,将有助于提高你的开发效率。

Java集合5-HashSet

wujianyouhun的专栏

03-05

510

HashSet的原理比较简单,几乎全部借助于HashMap来实现的。由于 HashSet 的底层是基于 HashMap 实现的,因此具有 HashMap 的特性,如高效的添加、查找操作(平均情况下为 O(1)),去重功能等。不过需要注意的是,HashSet 并不保证元素的顺序,元素存储的顺序与插入顺序可能不同,因为它是根据哈希值存储的。所以HashMap会出现的问题HashSet依然不能避免。

数组的访问2

程小白的博客

03-07

242

/ 数组的长度// 非空数组的最大索引 = array.length - 1。

Java的 Map以及实现一个简单的红黑树

好看的皮囊千篇一律,有趣的灵魂万里挑一。

03-07

1192

Map是将键映射到值的对象。map**不能包含重复的键**; 每个键最多只能映射到一个值。这个接口取代了Dictionary类,Dictionary类是一个完全抽象的类,而不是接口。

Map接口提供了三个集合视图,它们允许将映射的内容视为一组键、一组值或一组键-值映射。映射的顺序定义为映射集合视图上的迭代器返回其元素的顺序。一些类似实现,比如TreeMap类,对它们的顺序做出了特定的保证;其他类,如HashMap类,则不需要。

注意:如果使用可变对象作为映射键,必须非常小心。如果对象的值以影响相等比较的

【Web】浅聊JDBC的SPI机制是怎么实现的——DriverManager

uuzeray的博客

03-06

1415

【Web】浅浅地聊JDBC java.sql.Driver的SPI后门-CSDN博客上篇文章我们做到了知其然,知道了JDBC有SPI机制,并且可以利用其Driver后门这篇文章希望可以做到知其所以然,对JDBC的SPI机制的来源做到心里有数。

安卓Java面试题 31-40

我很好

03-08

135

比如说子线程更新UI,是因为触发了checkThread方法检查是否在主线程更新UI,还有就是子线程中没有Looper,这个原因是因为Handler的机制引起的,因为Handler发送Message的时候,需要将Message放到MessageQueue里面,而这个时候如果没有Looper的话,就无法循环输出MessageQueue了,这个时候就会报Looper为空的错误。7.套接字(socket ) : 套解字也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同及其间的进程通信。

java-初级项目实战-(swing篇)-羊了个羊(动态交互,)

qq_61549190的博客

03-04

556

判断t方格是否压住b方格,就要保证t方格的左上的黑点始终在蓝框内。即t的 x坐标(x1,x2)之间,y(y1,y2)之间。将下方图片添加到一个盒子中(简单的添加)添加一个新的集合,用于存储下方的图片。蓝框为b方格的宽度和高度的2倍,x1的x即为b的左上点x-其宽度。y1的y即为b的左上点y-其高度。y2的y即为b的左上点y+其高度。x2的x即为b左上点x+其宽度。t方格的黑点设置为(x,y)先检测2张牌是否压住。

面试 Java 基础八股文十问十答第十五期

qq_67358181的博客

03-05

1266

面试必备八股文!内容包含:Java基础、Java框架、Git命令、JVM、多线程、消息队列、微服务、Linux、数据库、Redis缓存、算法、Vue、React、前端性能优化等八股文。

Java并发编程-进程和线程

q1372302825的博客

03-05

632

进程和线程是计算机科学中重要的概念,用于管理程序的执行和资源分配。进程是操作系统中的一个独立执行单位,拥有自己的内存空间和系统资源。每个进程都可以包含一个或多个线程,线程是进程内的实际执行单元,共享相同的内存空间和资源。本文简要介绍了进程和线程的概念、特点以及它们在计算机系统中的作用。进程和线程的使用使得程序能够并发执行,提高了系统的效率和性能。然而,进程和线程的管理也面临着诸多挑战,如资源竞争、死锁等问题。因此,合理地使用和管理进程与线程对于保障系统稳定运行和提升性能至关重要。

MyBatis源码分析之基础支持层异常模块

个人博客,欢迎收藏。https://xiaoaozz.github.io/

03-05

469

MyBatis源码分析之基础支持层异常模块详解

Java8 使用 stream().sorted()对List集合进行排序

LuckyTHP

03-05

411

集合对象以学生类()为例,有学生的基本信息,包括:姓名,性别,年龄,身高,生日几项。使用stream().sorted()进行排序,需要该类实现Comparable接口,该接口只有一个方法需要实现,如下:Java 关于重写compareTo方法//名称 private String name;//性别 true男 false女 private Boolean gender;//年龄 private Integer age;//身高 private Double height;

方法设计时的注意规范

程小白的博客

03-07

268

【代码】方法设计时的注意规范。

java获取flv视频直播流地址的起始图片

最新发布

Dai_Haijiao的博客

03-08

119

从flv直播流地址中获取首帧图

java web中拦截器和过滤器的优缺点分别是什么?

FE攻城狮

03-07

113

在 Java Web 中,过滤器和拦截器的优缺点如下:

redistemplate原子类操作

08-11

回答: 在处理redis的数量时,可以使用redisTemplate提供的原子操作来保证数据的原子性。例如使用redisTemplate.opsForValue().increment()方法来进行加减操作,这样可以避免在高并发情况下出现先读后写或者后读先写的问题。同时,需要注意的是,在使用redisTemplate之前,需要先配置好redisTemplate及其子类,并使用@Resource注解进行调用。这样可以确保在代码中进行redis的原子操作。123

#### 引用[.reference_title]

- *1* *2* [JAVA操作REDIS执行原子操作](https://blog.csdn.net/qq_43021813/article/details/124426497)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}} ] [.reference_item]

- *3* [【redis】使用redisTemplate优雅地操作redis及使用redis实现分布式锁](https://blog.csdn.net/lovexiaotaozi/article/details/83505131)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}} ] [.reference_item]

[ .reference_list ]

“相关推荐”对你有帮助么?

非常没帮助

没帮助

一般

有帮助

非常有帮助

提交

WD技术

CSDN认证博客专家

CSDN认证企业博客

码龄5年

暂无认证

430

原创

7606

周排名

5778

总排名

42万+

访问

等级

4940

积分

320

粉丝

603

获赞

27

评论

873

收藏

私信

关注

热门文章

什么是守护线程?

16330

java 定义一个未知长度数组

12655

SQL中where与having的区别

12236

java 二维数组的定义

12157

IDEA中大小写转换快捷键

11707

分类专栏

工作中遇到的问题

51篇

java面试

框架面试

15篇

rabbitmq面试

23篇

javaWeb面试

14篇

java基础面试

24篇

多线程面试

40篇

jvm面试

20篇

mysql面试

36篇

数据结构面试

5篇

redis面试

23篇

hashmap面试

16篇

java基础

63篇

数据结构

1篇

mysql

9篇

springboot

12篇

aviator

1篇

json

1篇

spring-security

1篇

vscode

1篇

idea

29篇

spring

10篇

linux

2篇

maven

8篇

开发小技巧

4篇

javaWeb基础

8篇

多线程

3篇

springMvc

2篇

mybatis

3篇

xshell

1篇

tomcat

2篇

ssm整合

4篇

shiro

3篇

navicat

1篇

maven基础

1篇

最新评论

idea中build项目之后生成的target看不见

ITRunner123:

感谢解决了我的问题!

sql添加删除主键、外键

Lucky-GG:

alter table 表名 add constraint 外键约束名 foreign key(列名) references 引用外键表(列名)

如:

alter table Stu_PkFk_Sc

add constraint Fk_s

foreign key (sno)

references Stu_PkFk_S(sno)

什么是守护线程?

不爱说话的阿难:

例子中的意思是如果主线程已经结束时守护线程还没执行完,会伴随主线程的结束而结束。你在主线程中加了6s的睡眠,会使守护线程执行结束早于主线程,所以所有log都能打印出来

什么是守护线程?

凤凰涅槃:

main方法改成这样:

public static void main(String[] args) throws InterruptedException {

System.out.println("main begin....");

Thread thread1 = new MyThread1();

thread1.setName("线程A");

thread1.setDaemon(true);

thread1.start();

Thread.sleep(6000);

System.out.println("main end.....");

}加了Thread.sleep(6000)输出结果为

main begin....

线程A begin....

线程A end.....

main end.....

哪位大神能解释下呢

什么是最左匹配原则?

qq_43301530:

“又或者是b = 2 and b = 1” 打错了吧 应该是b =2 and a=1??

您愿意向朋友推荐“博客详情页”吗?

强烈不推荐

不推荐

一般般

推荐

强烈推荐

提交

最新文章

@RequestBody的使用

关于maven打包时,没有将依赖包打进来的问题

maven本地仓库有包,导致could not find artifact

2024年29篇

2023年22篇

2022年265篇

2021年114篇

目录

目录

分类专栏

工作中遇到的问题

51篇

java面试

框架面试

15篇

rabbitmq面试

23篇

javaWeb面试

14篇

java基础面试

24篇

多线程面试

40篇

jvm面试

20篇

mysql面试

36篇

数据结构面试

5篇

redis面试

23篇

hashmap面试

16篇

java基础

63篇

数据结构

1篇

mysql

9篇

springboot

12篇

aviator

1篇

json

1篇

spring-security

1篇

vscode

1篇

idea

29篇

spring

10篇

linux

2篇

maven

8篇

开发小技巧

4篇

javaWeb基础

8篇

多线程

3篇

springMvc

2篇

mybatis

3篇

xshell

1篇

tomcat

2篇

ssm整合

4篇

shiro

3篇

navicat

1篇

maven基础

1篇

目录

评论

被折叠的  条评论

为什么被折叠?

到【灌水乐园】发言

查看更多评论

添加红包

祝福语

请填写红包祝福语或标题

红包数量

红包个数最小为10个

红包总金额

红包金额最低5元

余额支付

当前余额3.43元

前往充值 >

需支付:10.00元

取消

确定

下一步

知道了

成就一亿技术人!

领取后你会自动成为博主和红包主的粉丝

规则

hope_wisdom 发出的红包

打赏作者

WD技术

你的鼓励将是我创作的最大动力

¥1

¥2

¥4

¥6

¥10

¥20

扫码支付:¥1

获取中

扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元

使用余额支付

点击重新获取

扫码支付

钱包余额

0

抵扣说明:

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

余额充值