Can synchronized blocks be faster than Atomics?

三世轮回 提交于 2019-12-14 03:39:43

问题


Suppose two following counter implementations:

class Counter {
  private final AtomicInteger atomic = new AtomicInteger(0);
  private int i = 0;

  public void incrementAtomic() {
    atomic.incrementAndGet();
  }

  public synchronized void increment() {
    i++;
  }
}

At first glance atomics should be faster and more scalable. And they are, I believe. But are they faster than synchronized blocks all the time? Or some situations exists when this rule is broken (e.g. SMP/Single CPU machine, different CPU ISA, OS'es etc.)?


回答1:


incrementAndGet may well be implemented as a CAS-loop. In highly contented situations that can result in n-1 of your threads failing leading to an O(n) problem, for n threads.

( For @Geek:

Typically getAndIncrement may be implemented something like:

 int old;
 do {
     old = value;
 } while (!compareAndSet(value, old, old+1));
 return old;

Imagine you have a n threads executing this code on the same atomic, and they happen to be in step with each other. The first iteration does kn work. Only one CAS will succeed. The other n-1 threads will repeat the exercise until there is only one left. So the total work is O(n^2) (worst case) instead of O(n). )

Having said that, acquiring a lock will need to do something similar at best, and locks aren't at their best when heavily contended. You're not likely to see much of an advantage for locks until you use a CAS-loop which requires significant computation before get and compareAndSwap.




回答2:


Or some situations exists when this rule is broken (e.g. SMP/Single CPU machine, different CPU ISA, OS'es etc.)?

I don't know of any. (And I stand ready to be corrected ... if someone knows of a concrete counter-example.)

However (and this is my main point) there is no theoretical reason why you couldn't have a hardware architecture or a poorly implemented JVM in which synchronized is the same speed or faster than the atomic types. (The relative speed of these two forms of synchronization is an implementation issue, and as such can only be quantified for existing implementations.)

And of course, this doesn't mean you should never use synchronized. The synchronized construct has many use-cases that the atomic classes don't address.




回答3:


It's implementation dependent - so ultimately you'll need to benchmark on your particualar platform / JVM / configuration.

Having said that, atomics should always be faster for the following reasons:

  • Atomics are designed so that the JVM can take advantage of atomic machine instructions, which are the fastest atomic operations that you can get for most platforms
  • synchronized makes use of relatively heavyweight locking schemes with monitor objects, which is designed to protect potentially large blocks of code. This form of locking in inherently more complicated than atomic operations so you would expect it to have higher runtime cost.



回答4:


As others have said this is implementation dependent . But keep in mind that if your program invariants involve more than one variable , then you have to use synchronization to update them together . You can't do atomic operation on two related variables together just because they are of Atomic type. In that case your only friend is synchronized .




回答5:


atomic variables will always be faster.

you can see that the java.util.concurrent package always utilises atomic variables rather than synchronized blocks.



来源:https://stackoverflow.com/questions/11551963/can-synchronized-blocks-be-faster-than-atomics

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!