When I was reading the code, I hit a class called
AtomicReference, so I checked it.
What is # Atmoic Reference
According to reference
A reference to the atomically updated object
With that. I don’t know if this is the only thing, but when carrying out concurrent programming, keep the shared objects that you want to update.
syncronize is expensive, and the
violatile keyword breaks when written at the same time.
It is a digression, but the intention of the
volatile keyword is to guarantee that the variable reference refers to the main memory, not the CPU cache. Variables without this keyword usually refer to the CPU cache. For systems with multiple CPUs, the same value may not always be referenced. Therefore, if you add the
volatile keyword, the main memory is referenced even if the CPU that is executing is different, so it is guaranteed that the same thing is referenced. Therefore, it is also called “guarantee of visibility”. By the way, the meaning of
volatile is a transitional meaning.
private volatile int counter = 0;
By the way, the explanation on this site was the best to understand. Since it is a site called
Java Concurrency, you can expect other articles.
On the other hand, AtmoicReference is a mechanism to refer and update from multiple threads without locking the lock with
AtomicReference<Integer> atomic = new AtomicReference<>(); System.out.println("atomic: "+ atomic.get()); atomic = new AtomicReference<>(10); System.out.println("atomic: "+ atomic.get());
atomic: null atomic: 10
By specifying the type like this, you can retain the value or refer to it by the
get() method. If you pass nothing to the constructor, it will be initialized with
A set of values.
atomic.set(100); System.out.println("atomic: "+ atomic.get());
Normally, I don’t think you use
set() that much. If it is updated by two threads, it will be the value updated later. If that’s OK, that’s fine. So there are methods like
getAndUpdate(). Pass in a lambda expression and update based on the current value. Some methods have the reverse order of
UnaryOperator operator = (v) -> (Integer)v + 1; System.out.println("atomic getAndUpdate: "+ atomic.getAndUpdate(operator)); System.out.println("atomic after getAndUpdate: "+ atomic.get()); System.out.println("atomic updateAndGet: "+ atomic.updateAndGet(operator));
atomic getAndUpdate: 20 atomic after getAndUpdate: 21 atomic updateAndGet: 22
There is also a method to write only when it is the expected value. The return value is
boolean, so I know if it was what I expected. This ensures that it has not been updated by another thread.
# At this point the value is 22 atomic.compareAndSet(23, 100); System.out.println("compareAndSet maybe not updated: "+ atomic.get());
compareAndSet maybe not updated: 22
By the way, there was a method called
weakCompareAndSet, and the result was the same, so why? If you think that, up to Java8, the implementation is the same as
compareAndSet, and since Java9 seems to be deprecated, please forget it.