java AtomicInteger 可以代替同步吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4210292/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 05:20:18  来源:igfitidea点击:

Can AtomicInteger replace synchronized?

java

提问by robbin

The javadoc for the java.util.concurrent.atomic package says the following:

java.util.concurrent.atomic 包的 javadoc 说明如下:

A small toolkit of classes that support lock-free thread-safe programming on single variables.

支持对单个变量进行无锁线程安全编程的小型类工具包。

But I don't see any thread-safe (synchronized or Lock) code inside any of the AtomicInteger or AtomicBoolean classes.

但是我在任何 AtomicInteger 或 AtomicBoolean 类中都没有看到任何线程安全(同步或锁定)代码。

So, are these 2 the same:

那么,这两个是否相同:

1.

1.

int i;
synchronized(this){i++;}

2.

2.

AtomicInteger i = new AtomicInteger();
i.getAndIncrement();

Update: Thanks for the answers. Is volatile needed when I use AtomicInteger?

更新:感谢您的回答。使用 AtomicInteger 时是否需要 volatile?

采纳答案by John Vint

They would offer the same atomicity. The only thing you must be aware of is any time you read i you must wrap it with synchronized also

它们将提供相同的原子性。您唯一必须注意的是,每次阅读时,您都必须使用 synchronized 包装它

synchronized(this){ return i;}

Edit to answer your edit:

编辑以回答您的编辑:

Volatile is not necessary for your AtomicInteger. To prove that declare the AtomicInteger final. The only reason you would need the AtomicInteger to be volatile is if the AtomicInteger field itself changes. Similar to:

您的 AtomicInteger 不需要 Volatile。为了证明声明 AtomicInteger final。您需要 AtomicInteger 可变的唯一原因是 AtomicInteger 字段本身是否发生变化。如同:

volatile AtomicInteger i = new AtomicInteger(0);

public void work(){
    i.incrementAndGet();
    //...do some other stuff
    i = new AtomicInteger(10);//because the field i is changing the field needs to be volatile 
}

As you can imagine that shouldn't be the case, so you shouldn't have to worry about the field being volatile.

正如您可以想象的那样,情况不应该如此,因此您不必担心该字段是不稳定的。

回答by Jim Garrison

They are equivalent functionally, but there is a subtle difference. synchronizedhas the overhead of acquiring and releasing the monitor on this, while AtomicIntegeris implemented with a native method call, so it will be significantly faster.

它们在功能上是等效的,但有细微的差别。synchronized有获取和释放监视器的开销this,而AtomicInteger通过本地方法调用来实现,所以它会明显更快。

回答by GaryF

Yes, they're functionally equivalent.

是的,它们在功能上是等效的。

If you're in an ultra-high contention environment, you may see performance differences, but that's highly unlikely.

如果您处于超高争用环境中,您可能会看到性能差异,但这极不可能。

回答by Jon

AtomicInteger uses sun.misc.Unsafe underneath to perform the atomic updates.

AtomicInteger 在底层使用 sun.misc.Unsafe 来执行原子更新。

So, in answer to your question, yes, AtomicInteger is thread-safe.

所以,回答你的问题,是的, AtomicInteger是线程安全的

回答by Stephen C

Is volatile needed when I use AtomicInteger?

使用 AtomicInteger 时是否需要 volatile?

Not necessarily. Considering your example:

不必要。考虑你的例子:

  • if iis a local variable, or
  • if iis a finalattribute, or
  • if the current thread and the thread that initialized (or last updated) the ivariable have synchronized after that event,
  • 如果i是局部变量,或
  • 如果i是一个final属性,或者
  • 如果当前线程和初始化(或上次更新)i变量的线程在该事件之后已同步,

then it makes no difference if you declare ias volatile or not.

那么您是否声明i为 volatile都没有区别。