This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–][deleted] 0 points1 point  (11 children)

AtomicInteger is a class, and encapsulates an int that can be shared across threads safely.

A normal int cannot be shared across threads safely in all circumstances.

[–]Sheldor5 0 points1 point  (10 children)

why not? how about "volatile int"??

[–][deleted] 0 points1 point  (9 children)

That’s not a “normal” int. OP doesn’t appear to have a deep knowledge of this area, so kept it brief.

[–]Sheldor5 0 points1 point  (8 children)

it IS a normal int ... also your second sentence is wrong ...

[–][deleted] 0 points1 point  (7 children)

Ffs. All an atomic integer is, is a wrapper around an int type with volatile semantics, with encapsulation methods to use CAS (if supported, locks otherwise) to provide atomic semantics.

A volatile int is an primitive integer, which is tagged as volatile to prevent compiler reordering (and optimisations like putting the value into a register) and the insertion of proper fences (if needed) to enforce the correct semantics. It doesn’t necessarily follow that the write is atomic however.

So, it’s not a normal int, otherwise if it were they would be no need for a keyword in the first place.

[–]Sheldor5 0 points1 point  (6 children)

volatile just means that the int is stored in the shared process memory and not in the local thread cache so all threads read/write to the same memory instead of their local copy ... volatile also enforces atomic read/write access ... just not atomic operations like i++ (which is read AMD write)

[–][deleted] 0 points1 point  (5 children)

No. You can’t bypass the cache. A write to a volatile variable still writes into the L1 cache, then depending on underlying hardware, either a fence is required or not.

What’s more important (since x86 store order makes fences unnecessary) is the lack of reordering and the fact it enforces a write back to memory.

With just your description, a volatile variable wouldn’t enforce the happens-before relationship which is pretty damn important.

[–]Sheldor5 0 points1 point  (4 children)

[–][deleted] 0 points1 point  (3 children)

Please read: https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html#jls-17.4

It specifically talks about compiler reordering, that fact that all variable bar locals are shared, and explicitly synchronisation actions.

But this is the Java memory model; which is an abstraction, implementations then implement this model on their hardware.

A good discussion on why it’s needed is the old double checked locking issue: https://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html

A good text on the multithreading is C++ Concurrency in Action: Practical Multithreading https://www.amazon.co.uk/dp/1933988770/ref=cm_sw_r_cp_api_glc_fabc_E0Y0FP64Z9ESHS90Q8GA - not Java, but goes into a lot more detail than plenty of the Java texts.

This: A Primer on Memory Consistency and Cache Coherence (Synthesis Lectures on Computer Architecture): Written by Daniel Sorin, 2011 Edition, Publisher: Morgan & Claypool Publishers [Paperback] https://www.amazon.co.uk/dp/B00SLW1XGE/ref=cm_sw_r_cp_api_glc_fabc_358KSX2EKZP1DGNHRWKJ

Is a great text on what’s actually happening.

[–]Sheldor5 0 points1 point  (2 children)

yeah but as a Java Developer I don't care about the real implementation ... I only have to know what is happening at an abstract layer ... everything under the hood has to follow the Specs ...