AtomicReference

Java AtomicMarkableReference Example

In this example we shall make use of AtomicMarkableReference class of Java. It is another class under the java.util.concurrent.atomic package, which provides lock-free and thread-safe programming solutions. In a recent example, we have seen how the AtomicReference class can be utilized to provide reference objects that may be atomically updated. Atomic actions are actions performed in an object only by one thread at a time.

The AtomicMarkableReference class may seem similar to the AtomicReference class, but it provides some extra information about the reference object. In particular an AtomicMarkableReference object maintains an object reference along with a mark bit. The object can be updated atomically, and it is actually a markable reference, since it is a two-value pair of the reference and the boolean mark.

In the example below, we have created an object of a custom class, Person. We have also created two threads that will both try to access a reference of the person object. In order to access the reference object, which is created with the AtomicMarkableReference, we make use of the API methods of the class, as explained below:

  • The AtomicMarkableReference(V initialRef, boolean initialMark) constructor creates a new AtomicMarkableReference object with the given initial object and an initial mark.
  • The attemptMark(V expectedReference, boolean newMark) method atomically sets the value of the mark to the given update value if the current reference is equal to the expected reference.
  • The compareAndSet(V expectedReference, V newReference, boolean expectedMark, boolean newMark) method atomically sets the value of both the reference and mark to the given update values if the current reference is equal to the expected reference and the current mark is equal to the expected mark.
  • The get(boolean[] markHolder) method returns the current values of both the reference and the mark, whereas the set(V newReference, boolean newMark) method unconditionally sets the value of both the reference and mark.
  • The getReference() method returns the current value of the reference, whereas isMarked() method returns the current value of the mark.

AtomicMarkableReferenceExample

package com.javacodegeeks.snippets.core;

import java.util.concurrent.atomic.AtomicMarkableReference;

public class AtomicMArkableReferenceExample {

	private static Person person;
	private static AtomicMarkableReference<Person> aMRperson;

	public static void main(String[] args) throws InterruptedException {
		Thread t1 = new Thread(new MyRun1());
		Thread t2 = new Thread(new MyRun2());
		person = new Person(15);
		aMRperson = new AtomicMarkableReference<Person>(person, false);
		System.out.println("Person is "	+ aMRperson.getReference() + "\nMark: "
						+ aMRperson.isMarked());
		t1.start();
		t2.start();
		t1.join();
		t2.join();
		System.out.println("\nNow Person is " + aMRperson.getReference() + "\nMark: "
				+ aMRperson.isMarked());
	}

	static class MyRun1 implements Runnable {

		public void run() {
			for (int i = 0; i <= 5; i++) {
				aMRperson.getReference().setAge(person.getAge()+1);
				aMRperson.compareAndSet(new Person(18), new Person(18), false, true);
				aMRperson.set(aMRperson.getReference(), true);
				System.out.println("\n" + Thread.currentThread().getName()
						+ " ---> " + aMRperson.getReference().toString() 
						+ "\nMark: " + aMRperson.isMarked());
			}
		}
	}

	static class MyRun2 implements Runnable {

		public void run() {
			for (int i = 0; i <= 5; i++) {
				aMRperson.getReference().setAge(person.getAge() - 1);
				aMRperson.attemptMark(new Person(40), true);
				System.out.println("\n" + Thread.currentThread().getName()
						+ " ---> " + aMRperson.getReference().toString()+ "\nMark: "
						+ aMRperson.isMarked());
			}
		}
	}

	static class Person {

		private int age;

		public Person(int age) {
			this.age = age;
		}

		public int getAge() {
			return age;
		}

		public void setAge(int age) {
			this.age = age;
		}
		
		@Override
		public String toString() {
			return "Person age is " + this.age;
		}
	}

}

If you run the example, the output will be something like the one below:

Output

Person is Person age is 15
Mark: false

Thread-0 ---> Person age is 15
Mark: true

Thread-1 ---> Person age is 15
Mark: true

Thread-0 ---> Person age is 16
Mark: true

Thread-1 ---> Person age is 15
Mark: true

Thread-0 ---> Person age is 16
Mark: true

Thread-1 ---> Person age is 15
Mark: true

Thread-0 ---> Person age is 16
Mark: true

Thread-1 ---> Person age is 15
Mark: true

Thread-0 ---> Person age is 16
Mark: true

Thread-1 ---> Person age is 15
Mark: true

Thread-0 ---> Person age is 16
Mark: true

Thread-1 ---> Person age is 15
Mark: true

Now Person is Person age is 15
Mark: true

This was an example of the AtomicMarkableReference class of Java.

Download
You can download the full source code of this example here: JavaAtomicMarkableReferenceExample

Theodora Fragkouli

Theodora has graduated from Computer Engineering and Informatics Department in the University of Patras. She also holds a Master degree in Economics from the National and Technical University of Athens. During her studies she has been involved with a large number of projects ranging from programming and software engineering to telecommunications, hardware design and analysis. She works as a junior Software Engineer in the telecommunications sector where she is mainly involved with projects based on Java and Big Data technologies.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Dmitry
Dmitry
5 years ago

Hi! Thanks for the useful explanation.
I’m a little confused of example.

From documentation (https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/package-summary.html): “…this package contains Updater classes that can be used to obtain compareAndSet operations on any selected volatile field of any selected class.”

So, shouldn’t field age be volatile?

Back to top button