[JAVA] A private note about AtomicReference

When I was doing code reading, I hit a class called ʻAtomicReference`, so I looked it up.

What is Atmoic Reference?

According to the Reference (https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/AtomicReference.html)

Atomicly updated object reference

That thing. I don't know if this is all, but when performing concurrent programming, keep the shared objects that you want to update. The syncronize is expensive, and the violatile keyword breaks when written at the same time.

volatile

Although derailed, the intent of the volatile keyword is to ensure that the variable reference refers to the main memory, not the CPU cache. Variables without this keyword usually refer to the CPU cache. In a system with multiple CPUs, the same value may not always be referenced. Therefore, if you add the volatile keyword, it will refer to the main memory even if the CPU running is different, so it is guaranteed to refer to the same one. Therefore, it is also called "guarantee of visibility". By the way, the meaning of volatile is easy to change.

private volatile int counter = 0;

By the way, the description on this site was great to understand. It's a site called Java Concurrency, so you can expect other articles.

AtomicReference

AtmoicReference, on the other hand, is a mechanism for referencing and updating from multiple threads without locking the lock with synchronized.

get()

	    AtomicReference<Integer> atomic = new AtomicReference<>();
	    System.out.println("atomic: "+ atomic.get());

	    atomic = new AtomicReference<>(10);
	    System.out.println("atomic: " + atomic.get());

result

atomic: null
atomic: 10

If you specify the type like this, you can keep the value or refer to it with the get () method. If nothing is passed to the constructor, it will be initialized with null.

set()

A set of values.

	    atomic.set(100);
		System.out.println("atomic: " + atomic.get());

result

atomic: 100

getAndUpdate()

Normally, I don't think you use set () that much. If it is updated in two threads, it will be the value updated later. If that's okay, that's fine. So there are methods like getAndUpdate (). Pass in a lambda expression to update based on the current value. Some methods have the order of ʻupdate and get` reversed.

		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));

result

atomic getAndUpdate: 20
atomic after getAndUpdate: 21
atomic updateAndGet: 22

compareAndSet()

Some methods write only when the value is expected. The return value is boolean, so you can tell if it was the expected value. This ensures that it has not been updated in any other thread.

                #At this point, the value is 22
		atomic.compareAndSet(23, 100);
		System.out.println("compareAndSet maybe not updated: " + atomic.get());

result

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 about it, the implementation is the same as compareAndSet up to Java8, and from Java9 it seems to be deprecated, so forget about it.

Reference

Recommended Posts

A private note about AtomicReference
A note about Java GC
A note about the scope
A note about RocksDB's Column Families
About private public
A note about adding Junit 4 to Android Studio
A note about the Rails and Vue process
Q & A about JDK
A rough note about Ruby arrays and hash objects
A note about th: field th: each th: object of thymeleaf
A note about the seed function of Ruby on Rails
A note when examining Javalin
About adding a like function
[Note] A story about changing Java build tools with VS Code
A murmur about the utility class
A little summary about typesafe config
A note about trying Oracle 11g + Spring boot with Vagrant + Docker compose