views:

559

answers:

4

Is there any difference in meaning of AtomicIntegerArray and AtomicInteger[]? And which one is faster to use? (only thing that I noticed is that first is taking much less space, but that means that each recheck is checking boundaries of array, so that would make it slower?)

Edit: In a scenario where array is pre-initialized.

+4  A: 

AtomicInteger[] will require an object per element. AtomicIntegerArray just requires the AtomicIntegerArray object and an array object. So use the latter if possible.

The cost of bounds checking is quite small even for normal arrays. What might be significant is that access to data in the same cache line from multiple processors can cause significant performance issues. Therefore separate objects, or deliberately avoiding close elements of an array, can help.

Tom Hawtin - tackline
Who cares about bounds checks? If you look at the (apparent) source code for, say, getAndSet it does the address calculation for both the get and the compareAndSet (although worse than this, most processors can do get-and-set without cas).
Tom Hawtin - tackline
tnx (didn't see your second paragraph there)So it might be good not to create all objects at the same time? (or with some random order?)
Sarmun
(I did a quick edit.) Creating objects at different times wont help as the GC will rearrange them. One of the classes in java.util.concurrent goes as far as to add lots of padding (in recent versions). It should be easier and clearer to add padding elements to AtomicIntegerArray, just shift left.
Tom Hawtin - tackline
A: 

I agree with Tom Hawin's first paragraph...

AtomicInteger[] will require an object per element. AtomicIntegerArray just requires the AtomicIntegerArray object and an array object. So use the latter if possible.

...but it should also be noted that AtomicInteger[] is not thread safe. Specifically, the array's references to the individual AtomicInteger objects may or may not be correct if accessed from multiple threads. Synchronizing access on the array object itself will eliminate this issue, though.

Stu Thompson
The point about Atomic* is that you avoid synchronisation. The assumed method of use of an AtomicInteger[] is to create all the AtomicIntegers once and only then publish the array safely.
Tom Hawtin - tackline
I agree. I'm not advocating using AtomicInteger[], just noting the difference, which is what the question was about :)
Stu Thompson
+3  A: 
  • AtomicInteger[] is an array of thread safe integers.
  • AtomicIntegerArray is a thread-safe array of integers.
ReneS
+2  A: 

Underneath, AtomicInteger and AtomicIntegerArray typically use the same low level APIs to perform reads, writes and other CAS operations. (For example, OpenSDK 7 uses sun.misc.Unsafe to perform the CAS operations in both classes.) So there is little performance benefit in using AtomicInteger[]. As you've already noted, the use of AtomicIntegerArray does have significant memory advantages.

On a practical note, the use of the later frees you from having to construct all your AtomicInteger instances, too. Remember that you cannot naively allocate those lazily due to concurrency reasons; you will have to pre-allocate or use some safe publishing mechanism. So in addition to memory advantages, your code is cleaner.

On a similar vein, if you have a bunch of objects with AtomicInteger members, for example:

class ReadCounter {
  private final String _fileName;
  private final AtomicInteger _readCount;
  ...
}

private final Map<String, ReadCounter> _counterByName = ...;

Then you can achieve similar memory improvements by modeling the member variable _readCount as a volatile int and using AtomicIntegerFieldUpdater.

Dilum Ranatunga
At the price of lower speed for updater operations (although get and set are fast). Sometimes it's worth extending from Atomic* as a memory saving hack.
Tom Hawtin - tackline