When to use AtomicReference in Java?












243















When do we use AtomicReference?



Is it needed to create objects in all multithreaded programs?



Provide a simple example where AtomicReference should be used.










share|improve this question





























    243















    When do we use AtomicReference?



    Is it needed to create objects in all multithreaded programs?



    Provide a simple example where AtomicReference should be used.










    share|improve this question



























      243












      243








      243


      98






      When do we use AtomicReference?



      Is it needed to create objects in all multithreaded programs?



      Provide a simple example where AtomicReference should be used.










      share|improve this question
















      When do we use AtomicReference?



      Is it needed to create objects in all multithreaded programs?



      Provide a simple example where AtomicReference should be used.







      java multithreading






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Dec 19 '16 at 14:01









      Ravindra babu

      29.7k5161136




      29.7k5161136










      asked Oct 18 '10 at 23:15









      ChintuChintu

      1,218294




      1,218294
























          8 Answers
          8






          active

          oldest

          votes


















          169














          Atomic reference should be used in a setting where you need to do simple atomic (i.e. thread safe, non-trivial) operations on a reference, for which monitor-based synchronization is not appropriate. Suppose you want to check to see if a specific field only if the state of the object remains as you last checked:



          AtomicReference<Object> cache = new AtomicReference<Object>();

          Object cachedValue = new Object();
          cache.set(cachedValue);

          //... time passes ...
          Object cachedValueToUpdate = cache.get();
          //... do some work to transform cachedValueToUpdate into a new version
          Object newValue = someFunctionOfOld(cachedValueToUpdate);
          boolean success = cache.compareAndSet(cachedValue,cachedValueToUpdate);


          Because of the atomic reference semantics, you can do this even if the cache object is shared amongst threads, without using synchronized. In general, you're better off using synchronizers or the java.util.concurrent framework rather than bare Atomic* unless you know what you're doing.



          Two excellent dead-tree references which will introduce you to this topic:




          • Herlihy's excellent Art of Multiprocessor Programming

          • Java Concurrency in Practice


          Note that (I don't know if this has always been true) reference assignment (i.e. =) is itself atomic (updating primitive 64-bit types like long or double may not be atomic; but updating a reference is always atomic, even if it's 64 bit) without explicitly using an Atomic*.

          See the Java Language Specification 3ed, Section 17.7.






          share|improve this answer





















          • 33





            Correct me if I'm wrong, but it seems like the key to needing this is because you need to do a "compareAndSet". If all I needed to do was set I wouldn't need the AtomicObject at all because of reference updates themselves being atomic?

            – sMoZely
            Jan 20 '13 at 21:46













          • Is it safe to do cache.compareAndSet(cachedValue, someFunctionOfOld(cachedValueToUpdate))? I.e. inline the computation?

            – kaqqao
            Dec 10 '13 at 12:07








          • 4





            @veggen Function arguments in Java are evaluated before function itself, so inlining makes no difference in this case. Yes, it is safe.

            – Dmitry
            Feb 19 '14 at 12:54






          • 24





            @sMoZely That is correct, but if you're not using AtomicReference you should mark the variable volatile because while the runtime guarantees that reference assignment is atomic, the compiler may perform optimizations under the assumption that the variable was not being modified by other threads.

            – kbolino
            Mar 14 '14 at 17:51








          • 1





            @BradCupit note that I said "if you're not using AtomicReference"; if you are using it, then my advice would be to go in the opposite direction and mark it final so the compiler can optimize accordingly.

            – kbolino
            Feb 19 '15 at 2:26



















          72














          An atomic reference is ideal to use when you need to share and change the state of an immutable object between multiple threads. That is a super dense statement so I will break it down a bit.



          First, an immutable object is an object that is effectively not changed after construction. Frequently an immutable object's methods return new instances of that same class. Some examples include the wrapper classes of Long and Double, as well as String, just to name a few. (According to Programming Concurrency on the JVM immutable objects are a critical part of modern concurrency).



          Next, why AtomicReference is better than a volatile object for sharing that shared value. A simple code example will show the difference.



          volatile String sharedValue;
          static final Object lock=new Object();
          void modifyString(){
          synchronized(lock){
          sharedValue=sharedValue+"something to add";
          }
          }


          Every time you want to modify the string referenced by that volatile field based on its current value, you first need to obtain a lock on that object. This prevents some other thread from coming in during the meantime and changing the value in the middle of the new string concatenation. Then when your thread resumes, you clobber the work of the other thread. But honestly that code will work, it looks clean, and it would make most people happy.



          Slight problem. It is slow. Especially if there is a lot of contention of that lock Object. Thats because most locks require an OS system call, and your thread will block and be context switched out of the CPU to make way for other processes.



          The other option is to use an AtomicRefrence.



          public static AtomicReference<String> shared = new AtomicReference<>();
          String init="Inital Value";
          shared.set(init);
          //now we will modify that value
          boolean success=false;
          while(!success){
          String prevValue=shared.get();
          // do all the work you need to
          String newValue=shared.get()+"lets add something";
          // Compare and set
          success=shared.compareAndSet(prevValue,newValue);
          }


          Now why is this better? Honestly that code is a little less clean than before. But there is something really important that happens under the hood in AtomicRefrence, and that is compare and swap.
          It is a single CPU instruction, not an OS call, that makes the switch happen. That is a single instruction on the CPU. And because there are no locks, there is no context switch in the case where the lock gets exercised which saves even more time!



          The catch is, for AtomicReferences, this does not use a .equals() call, but instead an == comparison for the expected value. So make sure the expected is the actual object returned from get in the loop.






          share|improve this answer





















          • 14





            Your two examples behave differently. You'd have to loop on worked to get the same semantics.

            – CurtainDog
            Oct 13 '14 at 20:32








          • 4





            I think you should initialize the value inside the AtomicReference constructor, otherwise another thread may still see the value null before you call shared.set. (Unless shared.set is run in a static initializer.)

            – Henno Vermeulen
            May 20 '15 at 9:35






          • 6





            In your second example, you should as of Java 8 use something like: shared.updateAndGet( (x) -> (x+"lets add something")); ... which will repeatedly call the .compareAndSet until it works. That is equivalent to the synchronized block which would always succeed. You need to ensure that the lambda you pass in is side-effect-free though because it may be called multiple times.

            – Tom Dibble
            Dec 9 '15 at 17:02













          • @CurtainDog Loop to hope that shared might become prevValue again? Good luck :)

            – Ivan Balashov
            Jul 14 '16 at 6:52






          • 2





            There is not need to make volatile String sharedValue. The synchronized(lock) is good enough to establish the happen before the relationship.

            – Jai Pandit
            Jul 20 '17 at 5:26



















          25














          Here is a use case for AtomicReference:



          Consider this class that acts as a number range, and uses individual AtmomicInteger variables to maintain lower and upper number bounds.



          public class NumberRange {
          // INVARIANT: lower <= upper
          private final AtomicInteger lower = new AtomicInteger(0);
          private final AtomicInteger upper = new AtomicInteger(0);

          public void setLower(int i) {
          // Warning -- unsafe check-then-act
          if (i > upper.get())
          throw new IllegalArgumentException(
          "can't set lower to " + i + " > upper");
          lower.set(i);
          }

          public void setUpper(int i) {
          // Warning -- unsafe check-then-act
          if (i < lower.get())
          throw new IllegalArgumentException(
          "can't set upper to " + i + " < lower");
          upper.set(i);
          }

          public boolean isInRange(int i) {
          return (i >= lower.get() && i <= upper.get());
          }
          }


          Both setLower and setUpper are check-then-act sequences, but they do not use sufficient locking to make them atomic. If the number range holds (0, 10), and one thread calls setLower(5) while another thread calls setUpper(4), with some unlucky timing both will pass the checks in the setters and both modifications will be applied. The result is that the range now holds (5, 4)an invalid state. So while the underlying AtomicIntegers are thread-safe, the composite class is not. This can be fixed by using a AtomicReference instead of using individual AtomicIntegers for upper and lower bounds.



          public class CasNumberRange {
          //Immutable
          private static class IntPair {
          final int lower; // Invariant: lower <= upper
          final int upper;
          ...
          }
          private final AtomicReference<IntPair> values =
          new AtomicReference<IntPair>(new IntPair(0, 0));

          public int getLower() { return values.get().lower; }
          public int getUpper() { return values.get().upper; }

          public void setLower(int i) {
          while (true) {
          IntPair oldv = values.get();
          if (i > oldv.upper)
          throw new IllegalArgumentException(
          "Can't set lower to " + i + " > upper");
          IntPair newv = new IntPair(i, oldv.upper);
          if (values.compareAndSet(oldv, newv))
          return;
          }
          }
          // similarly for setUpper
          }





          share|improve this answer



















          • 1





            This article is similar to your answer, but goes deep to more complicated things. It's interesting! ibm.com/developerworks/java/library/j-jtp04186

            – LppEdd
            Oct 8 '18 at 17:32



















          18














          You can use AtomicReference when applying optimistic locks. You have a shared object and you want to change it from more than 1 thread.




          1. You can create a copy of the shared object

          2. Modify the shared object

          3. You need to check that the shared object is still the same as before - if yes, then update with the reference of the modified copy.


          As other thread might have modified it and/can modify between these 2 steps. You need to do it in an atomic operation. this is where AtomicReference can help






          share|improve this answer































            3














            Here's a very simple use case and has nothing to do with thread safety.



            To share an object between lambda invocations, the AtomicReference is an option:



            public void doSomethingUsingLambdas() {

            AtomicReference<YourObject> yourObjectRef = new AtomicReference<>();

            soSomethingThatTakesALambda(() -> {
            yourObjectRef.set(youObject);
            });

            soSomethingElseThatTakesALambda(() -> {
            YourObject yourObject = yourObjectRef.get();
            });
            }


            I'm not saying this is good design or anything (it's just a trivial example), but if you have have the case where you need to share an object between lambda invocations, the AtomicReference is an option.



            In fact you can use any object that holds a reference, even a Collection that has only one item. However, the AtomicReference is a perfect fit.






            share|improve this answer































              3














              I won't talk much. Already my respected fellow friends have given their valuable input. The full fledged running code at the last of this blog should remove any confusion. It's about a movie seat booking small program in multi-threaded scenario.



              Some important elementary facts are as follows.
              1> Different threads can only contend for instance and static member variables in the heap space.
              2> Volatile read or write are completely atomic and serialized/happens before and only done from memory. By saying this I mean that any read will follow the previous write in memory. And any write will follow the previous read from memory. So any thread working with a volatile will always see the most up-to-date value.
              AtomicReference uses this property of volatile.



              Following are some of the source code of AtomicReference.
              AtomicReference refers to an object reference. This reference is a volatile member variable in the AtomicReference instance as below.



              private volatile V value;


              get() simply returns the latest value of the variable (as volatiles do in a "happens before" manner).



              public final V get()


              Following is the most important method of AtomicReference.



              public final boolean  compareAndSet(V expect, V update) {
              return unsafe.compareAndSwapObject(this, valueOffset, expect, update);
              }


              The compareAndSet(expect,update) method calls the compareAndSwapObject() method of the unsafe class of Java. This method call of unsafe invokes the native call, which invokes a single instruction to the processor. "expect" and "update" each reference an object.



              If and only if the AtomicReference instance member variable "value" refers to the same object is referred to by "expect", "update" is assigned to this instance variable now, and "true" is returned. Or else, false is returned. The whole thing is done atomically. No other thread can intercept in between.
              As this is a single processor operation (magic of modern computer architecture), it's often faster than using a synchronized block. But remember that when multiple variables need to be updated atomically, AtomicReference won't help.



              I would like to add a full fledged running code, which can be run in eclipse. It would clear many confusion. Here 22 users (MyTh threads) are trying to book 20 seats. Following is the code snippet followed by the full code.



              Code snippet where 22 users are trying to book 20 seats.



              for (int i = 0; i < 20; i++) {// 20 seats
              seats.add(new AtomicReference<Integer>());
              }
              Thread ths = new Thread[22];// 22 users
              for (int i = 0; i < ths.length; i++) {
              ths[i] = new MyTh(seats, i);
              ths[i].start();
              }


              Following is the full running code.



              import java.util.ArrayList;
              import java.util.List;
              import java.util.concurrent.ThreadLocalRandom;
              import java.util.concurrent.atomic.AtomicInteger;
              import java.util.concurrent.atomic.AtomicReference;

              public class Solution {

              static List<AtomicReference<Integer>> seats;// Movie seats numbered as per
              // list index

              public static void main(String args) throws InterruptedException {
              // TODO Auto-generated method stub
              seats = new ArrayList<>();
              for (int i = 0; i < 20; i++) {// 20 seats
              seats.add(new AtomicReference<Integer>());
              }
              Thread ths = new Thread[22];// 22 users
              for (int i = 0; i < ths.length; i++) {
              ths[i] = new MyTh(seats, i);
              ths[i].start();
              }
              for (Thread t : ths) {
              t.join();
              }
              for (AtomicReference<Integer> seat : seats) {
              System.out.print(" " + seat.get());
              }
              }

              /**
              * id is the id of the user
              *
              * @author sankbane
              *
              */
              static class MyTh extends Thread {// each thread is a user
              static AtomicInteger full = new AtomicInteger(0);
              List<AtomicReference<Integer>> l;//seats
              int id;//id of the users
              int seats;

              public MyTh(List<AtomicReference<Integer>> list, int userId) {
              l = list;
              this.id = userId;
              seats = list.size();
              }

              @Override
              public void run() {
              boolean reserved = false;
              try {
              while (!reserved && full.get() < seats) {
              Thread.sleep(50);
              int r = ThreadLocalRandom.current().nextInt(0, seats);// excludes
              // seats
              //
              AtomicReference<Integer> el = l.get(r);
              reserved = el.compareAndSet(null, id);// null means no user
              // has reserved this
              // seat
              if (reserved)
              full.getAndIncrement();
              }
              if (!reserved && full.get() == seats)
              System.out.println("user " + id + " did not get a seat");
              } catch (InterruptedException ie) {
              // log it
              }
              }
              }

              }





              share|improve this answer

































                2















                When do we use AtomicReference?




                AtomicReference is flexible way to update the variable value atomically without use of synchronization.



                AtomicReference support lock-free thread-safe programming on single variables.



                There are multiple ways of achieving Thread safety with high level concurrent API. Atomic variables is one of the multiple options.



                Lock objects support locking idioms that simplify many concurrent applications.



                Executors define a high-level API for launching and managing threads. Executor implementations provided by java.util.concurrent provide thread pool management suitable for large-scale applications.



                Concurrent collections make it easier to manage large collections of data, and can greatly reduce the need for synchronization.



                Atomic variables have features that minimize synchronization and help avoid memory consistency errors.




                Provide a simple example where AtomicReference should be used.




                Sample code with AtomicReference:



                String initialReference = "value 1";

                AtomicReference<String> someRef =
                new AtomicReference<String>(initialReference);

                String newReference = "value 2";
                boolean exchanged = someRef.compareAndSet(initialReference, newReference);
                System.out.println("exchanged: " + exchanged);



                Is it needed to create objects in all multithreaded programs?




                You don't have to use AtomicReference in all multi threaded programs.



                If you want to guard a single variable, use AtomicReference. If you want to guard a code block, use other constructs like Lock /synchronized etc.






                share|improve this answer

































                  -1














                  Another simple example is to do a safe-thread modification in a session object.



                  public PlayerScore getHighScore() {
                  ServletContext ctx = getServletConfig().getServletContext();
                  AtomicReference<PlayerScore> holder
                  = (AtomicReference<PlayerScore>) ctx.getAttribute("highScore");
                  return holder.get();
                  }

                  public void updateHighScore(PlayerScore newScore) {
                  ServletContext ctx = getServletConfig().getServletContext();
                  AtomicReference<PlayerScore> holder
                  = (AtomicReference<PlayerScore>) ctx.getAttribute("highScore");
                  while (true) {
                  HighScore old = holder.get();
                  if (old.score >= newScore.score)
                  break;
                  else if (holder.compareAndSet(old, newScore))
                  break;
                  }
                  }


                  Source: http://www.ibm.com/developerworks/library/j-jtp09238/index.html






                  share|improve this answer























                    Your Answer






                    StackExchange.ifUsing("editor", function () {
                    StackExchange.using("externalEditor", function () {
                    StackExchange.using("snippets", function () {
                    StackExchange.snippets.init();
                    });
                    });
                    }, "code-snippets");

                    StackExchange.ready(function() {
                    var channelOptions = {
                    tags: "".split(" "),
                    id: "1"
                    };
                    initTagRenderer("".split(" "), "".split(" "), channelOptions);

                    StackExchange.using("externalEditor", function() {
                    // Have to fire editor after snippets, if snippets enabled
                    if (StackExchange.settings.snippets.snippetsEnabled) {
                    StackExchange.using("snippets", function() {
                    createEditor();
                    });
                    }
                    else {
                    createEditor();
                    }
                    });

                    function createEditor() {
                    StackExchange.prepareEditor({
                    heartbeatType: 'answer',
                    autoActivateHeartbeat: false,
                    convertImagesToLinks: true,
                    noModals: true,
                    showLowRepImageUploadWarning: true,
                    reputationToPostImages: 10,
                    bindNavPrevention: true,
                    postfix: "",
                    imageUploader: {
                    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
                    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
                    allowUrls: true
                    },
                    onDemand: true,
                    discardSelector: ".discard-answer"
                    ,immediatelyShowMarkdownHelp:true
                    });


                    }
                    });














                    draft saved

                    draft discarded


















                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f3964211%2fwhen-to-use-atomicreference-in-java%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown

























                    8 Answers
                    8






                    active

                    oldest

                    votes








                    8 Answers
                    8






                    active

                    oldest

                    votes









                    active

                    oldest

                    votes






                    active

                    oldest

                    votes









                    169














                    Atomic reference should be used in a setting where you need to do simple atomic (i.e. thread safe, non-trivial) operations on a reference, for which monitor-based synchronization is not appropriate. Suppose you want to check to see if a specific field only if the state of the object remains as you last checked:



                    AtomicReference<Object> cache = new AtomicReference<Object>();

                    Object cachedValue = new Object();
                    cache.set(cachedValue);

                    //... time passes ...
                    Object cachedValueToUpdate = cache.get();
                    //... do some work to transform cachedValueToUpdate into a new version
                    Object newValue = someFunctionOfOld(cachedValueToUpdate);
                    boolean success = cache.compareAndSet(cachedValue,cachedValueToUpdate);


                    Because of the atomic reference semantics, you can do this even if the cache object is shared amongst threads, without using synchronized. In general, you're better off using synchronizers or the java.util.concurrent framework rather than bare Atomic* unless you know what you're doing.



                    Two excellent dead-tree references which will introduce you to this topic:




                    • Herlihy's excellent Art of Multiprocessor Programming

                    • Java Concurrency in Practice


                    Note that (I don't know if this has always been true) reference assignment (i.e. =) is itself atomic (updating primitive 64-bit types like long or double may not be atomic; but updating a reference is always atomic, even if it's 64 bit) without explicitly using an Atomic*.

                    See the Java Language Specification 3ed, Section 17.7.






                    share|improve this answer





















                    • 33





                      Correct me if I'm wrong, but it seems like the key to needing this is because you need to do a "compareAndSet". If all I needed to do was set I wouldn't need the AtomicObject at all because of reference updates themselves being atomic?

                      – sMoZely
                      Jan 20 '13 at 21:46













                    • Is it safe to do cache.compareAndSet(cachedValue, someFunctionOfOld(cachedValueToUpdate))? I.e. inline the computation?

                      – kaqqao
                      Dec 10 '13 at 12:07








                    • 4





                      @veggen Function arguments in Java are evaluated before function itself, so inlining makes no difference in this case. Yes, it is safe.

                      – Dmitry
                      Feb 19 '14 at 12:54






                    • 24





                      @sMoZely That is correct, but if you're not using AtomicReference you should mark the variable volatile because while the runtime guarantees that reference assignment is atomic, the compiler may perform optimizations under the assumption that the variable was not being modified by other threads.

                      – kbolino
                      Mar 14 '14 at 17:51








                    • 1





                      @BradCupit note that I said "if you're not using AtomicReference"; if you are using it, then my advice would be to go in the opposite direction and mark it final so the compiler can optimize accordingly.

                      – kbolino
                      Feb 19 '15 at 2:26
















                    169














                    Atomic reference should be used in a setting where you need to do simple atomic (i.e. thread safe, non-trivial) operations on a reference, for which monitor-based synchronization is not appropriate. Suppose you want to check to see if a specific field only if the state of the object remains as you last checked:



                    AtomicReference<Object> cache = new AtomicReference<Object>();

                    Object cachedValue = new Object();
                    cache.set(cachedValue);

                    //... time passes ...
                    Object cachedValueToUpdate = cache.get();
                    //... do some work to transform cachedValueToUpdate into a new version
                    Object newValue = someFunctionOfOld(cachedValueToUpdate);
                    boolean success = cache.compareAndSet(cachedValue,cachedValueToUpdate);


                    Because of the atomic reference semantics, you can do this even if the cache object is shared amongst threads, without using synchronized. In general, you're better off using synchronizers or the java.util.concurrent framework rather than bare Atomic* unless you know what you're doing.



                    Two excellent dead-tree references which will introduce you to this topic:




                    • Herlihy's excellent Art of Multiprocessor Programming

                    • Java Concurrency in Practice


                    Note that (I don't know if this has always been true) reference assignment (i.e. =) is itself atomic (updating primitive 64-bit types like long or double may not be atomic; but updating a reference is always atomic, even if it's 64 bit) without explicitly using an Atomic*.

                    See the Java Language Specification 3ed, Section 17.7.






                    share|improve this answer





















                    • 33





                      Correct me if I'm wrong, but it seems like the key to needing this is because you need to do a "compareAndSet". If all I needed to do was set I wouldn't need the AtomicObject at all because of reference updates themselves being atomic?

                      – sMoZely
                      Jan 20 '13 at 21:46













                    • Is it safe to do cache.compareAndSet(cachedValue, someFunctionOfOld(cachedValueToUpdate))? I.e. inline the computation?

                      – kaqqao
                      Dec 10 '13 at 12:07








                    • 4





                      @veggen Function arguments in Java are evaluated before function itself, so inlining makes no difference in this case. Yes, it is safe.

                      – Dmitry
                      Feb 19 '14 at 12:54






                    • 24





                      @sMoZely That is correct, but if you're not using AtomicReference you should mark the variable volatile because while the runtime guarantees that reference assignment is atomic, the compiler may perform optimizations under the assumption that the variable was not being modified by other threads.

                      – kbolino
                      Mar 14 '14 at 17:51








                    • 1





                      @BradCupit note that I said "if you're not using AtomicReference"; if you are using it, then my advice would be to go in the opposite direction and mark it final so the compiler can optimize accordingly.

                      – kbolino
                      Feb 19 '15 at 2:26














                    169












                    169








                    169







                    Atomic reference should be used in a setting where you need to do simple atomic (i.e. thread safe, non-trivial) operations on a reference, for which monitor-based synchronization is not appropriate. Suppose you want to check to see if a specific field only if the state of the object remains as you last checked:



                    AtomicReference<Object> cache = new AtomicReference<Object>();

                    Object cachedValue = new Object();
                    cache.set(cachedValue);

                    //... time passes ...
                    Object cachedValueToUpdate = cache.get();
                    //... do some work to transform cachedValueToUpdate into a new version
                    Object newValue = someFunctionOfOld(cachedValueToUpdate);
                    boolean success = cache.compareAndSet(cachedValue,cachedValueToUpdate);


                    Because of the atomic reference semantics, you can do this even if the cache object is shared amongst threads, without using synchronized. In general, you're better off using synchronizers or the java.util.concurrent framework rather than bare Atomic* unless you know what you're doing.



                    Two excellent dead-tree references which will introduce you to this topic:




                    • Herlihy's excellent Art of Multiprocessor Programming

                    • Java Concurrency in Practice


                    Note that (I don't know if this has always been true) reference assignment (i.e. =) is itself atomic (updating primitive 64-bit types like long or double may not be atomic; but updating a reference is always atomic, even if it's 64 bit) without explicitly using an Atomic*.

                    See the Java Language Specification 3ed, Section 17.7.






                    share|improve this answer















                    Atomic reference should be used in a setting where you need to do simple atomic (i.e. thread safe, non-trivial) operations on a reference, for which monitor-based synchronization is not appropriate. Suppose you want to check to see if a specific field only if the state of the object remains as you last checked:



                    AtomicReference<Object> cache = new AtomicReference<Object>();

                    Object cachedValue = new Object();
                    cache.set(cachedValue);

                    //... time passes ...
                    Object cachedValueToUpdate = cache.get();
                    //... do some work to transform cachedValueToUpdate into a new version
                    Object newValue = someFunctionOfOld(cachedValueToUpdate);
                    boolean success = cache.compareAndSet(cachedValue,cachedValueToUpdate);


                    Because of the atomic reference semantics, you can do this even if the cache object is shared amongst threads, without using synchronized. In general, you're better off using synchronizers or the java.util.concurrent framework rather than bare Atomic* unless you know what you're doing.



                    Two excellent dead-tree references which will introduce you to this topic:




                    • Herlihy's excellent Art of Multiprocessor Programming

                    • Java Concurrency in Practice


                    Note that (I don't know if this has always been true) reference assignment (i.e. =) is itself atomic (updating primitive 64-bit types like long or double may not be atomic; but updating a reference is always atomic, even if it's 64 bit) without explicitly using an Atomic*.

                    See the Java Language Specification 3ed, Section 17.7.







                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited Apr 3 '18 at 11:56









                    informatik01

                    13.1k85589




                    13.1k85589










                    answered Oct 18 '10 at 23:22









                    andersojandersoj

                    17.3k64971




                    17.3k64971








                    • 33





                      Correct me if I'm wrong, but it seems like the key to needing this is because you need to do a "compareAndSet". If all I needed to do was set I wouldn't need the AtomicObject at all because of reference updates themselves being atomic?

                      – sMoZely
                      Jan 20 '13 at 21:46













                    • Is it safe to do cache.compareAndSet(cachedValue, someFunctionOfOld(cachedValueToUpdate))? I.e. inline the computation?

                      – kaqqao
                      Dec 10 '13 at 12:07








                    • 4





                      @veggen Function arguments in Java are evaluated before function itself, so inlining makes no difference in this case. Yes, it is safe.

                      – Dmitry
                      Feb 19 '14 at 12:54






                    • 24





                      @sMoZely That is correct, but if you're not using AtomicReference you should mark the variable volatile because while the runtime guarantees that reference assignment is atomic, the compiler may perform optimizations under the assumption that the variable was not being modified by other threads.

                      – kbolino
                      Mar 14 '14 at 17:51








                    • 1





                      @BradCupit note that I said "if you're not using AtomicReference"; if you are using it, then my advice would be to go in the opposite direction and mark it final so the compiler can optimize accordingly.

                      – kbolino
                      Feb 19 '15 at 2:26














                    • 33





                      Correct me if I'm wrong, but it seems like the key to needing this is because you need to do a "compareAndSet". If all I needed to do was set I wouldn't need the AtomicObject at all because of reference updates themselves being atomic?

                      – sMoZely
                      Jan 20 '13 at 21:46













                    • Is it safe to do cache.compareAndSet(cachedValue, someFunctionOfOld(cachedValueToUpdate))? I.e. inline the computation?

                      – kaqqao
                      Dec 10 '13 at 12:07








                    • 4





                      @veggen Function arguments in Java are evaluated before function itself, so inlining makes no difference in this case. Yes, it is safe.

                      – Dmitry
                      Feb 19 '14 at 12:54






                    • 24





                      @sMoZely That is correct, but if you're not using AtomicReference you should mark the variable volatile because while the runtime guarantees that reference assignment is atomic, the compiler may perform optimizations under the assumption that the variable was not being modified by other threads.

                      – kbolino
                      Mar 14 '14 at 17:51








                    • 1





                      @BradCupit note that I said "if you're not using AtomicReference"; if you are using it, then my advice would be to go in the opposite direction and mark it final so the compiler can optimize accordingly.

                      – kbolino
                      Feb 19 '15 at 2:26








                    33




                    33





                    Correct me if I'm wrong, but it seems like the key to needing this is because you need to do a "compareAndSet". If all I needed to do was set I wouldn't need the AtomicObject at all because of reference updates themselves being atomic?

                    – sMoZely
                    Jan 20 '13 at 21:46







                    Correct me if I'm wrong, but it seems like the key to needing this is because you need to do a "compareAndSet". If all I needed to do was set I wouldn't need the AtomicObject at all because of reference updates themselves being atomic?

                    – sMoZely
                    Jan 20 '13 at 21:46















                    Is it safe to do cache.compareAndSet(cachedValue, someFunctionOfOld(cachedValueToUpdate))? I.e. inline the computation?

                    – kaqqao
                    Dec 10 '13 at 12:07







                    Is it safe to do cache.compareAndSet(cachedValue, someFunctionOfOld(cachedValueToUpdate))? I.e. inline the computation?

                    – kaqqao
                    Dec 10 '13 at 12:07






                    4




                    4





                    @veggen Function arguments in Java are evaluated before function itself, so inlining makes no difference in this case. Yes, it is safe.

                    – Dmitry
                    Feb 19 '14 at 12:54





                    @veggen Function arguments in Java are evaluated before function itself, so inlining makes no difference in this case. Yes, it is safe.

                    – Dmitry
                    Feb 19 '14 at 12:54




                    24




                    24





                    @sMoZely That is correct, but if you're not using AtomicReference you should mark the variable volatile because while the runtime guarantees that reference assignment is atomic, the compiler may perform optimizations under the assumption that the variable was not being modified by other threads.

                    – kbolino
                    Mar 14 '14 at 17:51







                    @sMoZely That is correct, but if you're not using AtomicReference you should mark the variable volatile because while the runtime guarantees that reference assignment is atomic, the compiler may perform optimizations under the assumption that the variable was not being modified by other threads.

                    – kbolino
                    Mar 14 '14 at 17:51






                    1




                    1





                    @BradCupit note that I said "if you're not using AtomicReference"; if you are using it, then my advice would be to go in the opposite direction and mark it final so the compiler can optimize accordingly.

                    – kbolino
                    Feb 19 '15 at 2:26





                    @BradCupit note that I said "if you're not using AtomicReference"; if you are using it, then my advice would be to go in the opposite direction and mark it final so the compiler can optimize accordingly.

                    – kbolino
                    Feb 19 '15 at 2:26













                    72














                    An atomic reference is ideal to use when you need to share and change the state of an immutable object between multiple threads. That is a super dense statement so I will break it down a bit.



                    First, an immutable object is an object that is effectively not changed after construction. Frequently an immutable object's methods return new instances of that same class. Some examples include the wrapper classes of Long and Double, as well as String, just to name a few. (According to Programming Concurrency on the JVM immutable objects are a critical part of modern concurrency).



                    Next, why AtomicReference is better than a volatile object for sharing that shared value. A simple code example will show the difference.



                    volatile String sharedValue;
                    static final Object lock=new Object();
                    void modifyString(){
                    synchronized(lock){
                    sharedValue=sharedValue+"something to add";
                    }
                    }


                    Every time you want to modify the string referenced by that volatile field based on its current value, you first need to obtain a lock on that object. This prevents some other thread from coming in during the meantime and changing the value in the middle of the new string concatenation. Then when your thread resumes, you clobber the work of the other thread. But honestly that code will work, it looks clean, and it would make most people happy.



                    Slight problem. It is slow. Especially if there is a lot of contention of that lock Object. Thats because most locks require an OS system call, and your thread will block and be context switched out of the CPU to make way for other processes.



                    The other option is to use an AtomicRefrence.



                    public static AtomicReference<String> shared = new AtomicReference<>();
                    String init="Inital Value";
                    shared.set(init);
                    //now we will modify that value
                    boolean success=false;
                    while(!success){
                    String prevValue=shared.get();
                    // do all the work you need to
                    String newValue=shared.get()+"lets add something";
                    // Compare and set
                    success=shared.compareAndSet(prevValue,newValue);
                    }


                    Now why is this better? Honestly that code is a little less clean than before. But there is something really important that happens under the hood in AtomicRefrence, and that is compare and swap.
                    It is a single CPU instruction, not an OS call, that makes the switch happen. That is a single instruction on the CPU. And because there are no locks, there is no context switch in the case where the lock gets exercised which saves even more time!



                    The catch is, for AtomicReferences, this does not use a .equals() call, but instead an == comparison for the expected value. So make sure the expected is the actual object returned from get in the loop.






                    share|improve this answer





















                    • 14





                      Your two examples behave differently. You'd have to loop on worked to get the same semantics.

                      – CurtainDog
                      Oct 13 '14 at 20:32








                    • 4





                      I think you should initialize the value inside the AtomicReference constructor, otherwise another thread may still see the value null before you call shared.set. (Unless shared.set is run in a static initializer.)

                      – Henno Vermeulen
                      May 20 '15 at 9:35






                    • 6





                      In your second example, you should as of Java 8 use something like: shared.updateAndGet( (x) -> (x+"lets add something")); ... which will repeatedly call the .compareAndSet until it works. That is equivalent to the synchronized block which would always succeed. You need to ensure that the lambda you pass in is side-effect-free though because it may be called multiple times.

                      – Tom Dibble
                      Dec 9 '15 at 17:02













                    • @CurtainDog Loop to hope that shared might become prevValue again? Good luck :)

                      – Ivan Balashov
                      Jul 14 '16 at 6:52






                    • 2





                      There is not need to make volatile String sharedValue. The synchronized(lock) is good enough to establish the happen before the relationship.

                      – Jai Pandit
                      Jul 20 '17 at 5:26
















                    72














                    An atomic reference is ideal to use when you need to share and change the state of an immutable object between multiple threads. That is a super dense statement so I will break it down a bit.



                    First, an immutable object is an object that is effectively not changed after construction. Frequently an immutable object's methods return new instances of that same class. Some examples include the wrapper classes of Long and Double, as well as String, just to name a few. (According to Programming Concurrency on the JVM immutable objects are a critical part of modern concurrency).



                    Next, why AtomicReference is better than a volatile object for sharing that shared value. A simple code example will show the difference.



                    volatile String sharedValue;
                    static final Object lock=new Object();
                    void modifyString(){
                    synchronized(lock){
                    sharedValue=sharedValue+"something to add";
                    }
                    }


                    Every time you want to modify the string referenced by that volatile field based on its current value, you first need to obtain a lock on that object. This prevents some other thread from coming in during the meantime and changing the value in the middle of the new string concatenation. Then when your thread resumes, you clobber the work of the other thread. But honestly that code will work, it looks clean, and it would make most people happy.



                    Slight problem. It is slow. Especially if there is a lot of contention of that lock Object. Thats because most locks require an OS system call, and your thread will block and be context switched out of the CPU to make way for other processes.



                    The other option is to use an AtomicRefrence.



                    public static AtomicReference<String> shared = new AtomicReference<>();
                    String init="Inital Value";
                    shared.set(init);
                    //now we will modify that value
                    boolean success=false;
                    while(!success){
                    String prevValue=shared.get();
                    // do all the work you need to
                    String newValue=shared.get()+"lets add something";
                    // Compare and set
                    success=shared.compareAndSet(prevValue,newValue);
                    }


                    Now why is this better? Honestly that code is a little less clean than before. But there is something really important that happens under the hood in AtomicRefrence, and that is compare and swap.
                    It is a single CPU instruction, not an OS call, that makes the switch happen. That is a single instruction on the CPU. And because there are no locks, there is no context switch in the case where the lock gets exercised which saves even more time!



                    The catch is, for AtomicReferences, this does not use a .equals() call, but instead an == comparison for the expected value. So make sure the expected is the actual object returned from get in the loop.






                    share|improve this answer





















                    • 14





                      Your two examples behave differently. You'd have to loop on worked to get the same semantics.

                      – CurtainDog
                      Oct 13 '14 at 20:32








                    • 4





                      I think you should initialize the value inside the AtomicReference constructor, otherwise another thread may still see the value null before you call shared.set. (Unless shared.set is run in a static initializer.)

                      – Henno Vermeulen
                      May 20 '15 at 9:35






                    • 6





                      In your second example, you should as of Java 8 use something like: shared.updateAndGet( (x) -> (x+"lets add something")); ... which will repeatedly call the .compareAndSet until it works. That is equivalent to the synchronized block which would always succeed. You need to ensure that the lambda you pass in is side-effect-free though because it may be called multiple times.

                      – Tom Dibble
                      Dec 9 '15 at 17:02













                    • @CurtainDog Loop to hope that shared might become prevValue again? Good luck :)

                      – Ivan Balashov
                      Jul 14 '16 at 6:52






                    • 2





                      There is not need to make volatile String sharedValue. The synchronized(lock) is good enough to establish the happen before the relationship.

                      – Jai Pandit
                      Jul 20 '17 at 5:26














                    72












                    72








                    72







                    An atomic reference is ideal to use when you need to share and change the state of an immutable object between multiple threads. That is a super dense statement so I will break it down a bit.



                    First, an immutable object is an object that is effectively not changed after construction. Frequently an immutable object's methods return new instances of that same class. Some examples include the wrapper classes of Long and Double, as well as String, just to name a few. (According to Programming Concurrency on the JVM immutable objects are a critical part of modern concurrency).



                    Next, why AtomicReference is better than a volatile object for sharing that shared value. A simple code example will show the difference.



                    volatile String sharedValue;
                    static final Object lock=new Object();
                    void modifyString(){
                    synchronized(lock){
                    sharedValue=sharedValue+"something to add";
                    }
                    }


                    Every time you want to modify the string referenced by that volatile field based on its current value, you first need to obtain a lock on that object. This prevents some other thread from coming in during the meantime and changing the value in the middle of the new string concatenation. Then when your thread resumes, you clobber the work of the other thread. But honestly that code will work, it looks clean, and it would make most people happy.



                    Slight problem. It is slow. Especially if there is a lot of contention of that lock Object. Thats because most locks require an OS system call, and your thread will block and be context switched out of the CPU to make way for other processes.



                    The other option is to use an AtomicRefrence.



                    public static AtomicReference<String> shared = new AtomicReference<>();
                    String init="Inital Value";
                    shared.set(init);
                    //now we will modify that value
                    boolean success=false;
                    while(!success){
                    String prevValue=shared.get();
                    // do all the work you need to
                    String newValue=shared.get()+"lets add something";
                    // Compare and set
                    success=shared.compareAndSet(prevValue,newValue);
                    }


                    Now why is this better? Honestly that code is a little less clean than before. But there is something really important that happens under the hood in AtomicRefrence, and that is compare and swap.
                    It is a single CPU instruction, not an OS call, that makes the switch happen. That is a single instruction on the CPU. And because there are no locks, there is no context switch in the case where the lock gets exercised which saves even more time!



                    The catch is, for AtomicReferences, this does not use a .equals() call, but instead an == comparison for the expected value. So make sure the expected is the actual object returned from get in the loop.






                    share|improve this answer















                    An atomic reference is ideal to use when you need to share and change the state of an immutable object between multiple threads. That is a super dense statement so I will break it down a bit.



                    First, an immutable object is an object that is effectively not changed after construction. Frequently an immutable object's methods return new instances of that same class. Some examples include the wrapper classes of Long and Double, as well as String, just to name a few. (According to Programming Concurrency on the JVM immutable objects are a critical part of modern concurrency).



                    Next, why AtomicReference is better than a volatile object for sharing that shared value. A simple code example will show the difference.



                    volatile String sharedValue;
                    static final Object lock=new Object();
                    void modifyString(){
                    synchronized(lock){
                    sharedValue=sharedValue+"something to add";
                    }
                    }


                    Every time you want to modify the string referenced by that volatile field based on its current value, you first need to obtain a lock on that object. This prevents some other thread from coming in during the meantime and changing the value in the middle of the new string concatenation. Then when your thread resumes, you clobber the work of the other thread. But honestly that code will work, it looks clean, and it would make most people happy.



                    Slight problem. It is slow. Especially if there is a lot of contention of that lock Object. Thats because most locks require an OS system call, and your thread will block and be context switched out of the CPU to make way for other processes.



                    The other option is to use an AtomicRefrence.



                    public static AtomicReference<String> shared = new AtomicReference<>();
                    String init="Inital Value";
                    shared.set(init);
                    //now we will modify that value
                    boolean success=false;
                    while(!success){
                    String prevValue=shared.get();
                    // do all the work you need to
                    String newValue=shared.get()+"lets add something";
                    // Compare and set
                    success=shared.compareAndSet(prevValue,newValue);
                    }


                    Now why is this better? Honestly that code is a little less clean than before. But there is something really important that happens under the hood in AtomicRefrence, and that is compare and swap.
                    It is a single CPU instruction, not an OS call, that makes the switch happen. That is a single instruction on the CPU. And because there are no locks, there is no context switch in the case where the lock gets exercised which saves even more time!



                    The catch is, for AtomicReferences, this does not use a .equals() call, but instead an == comparison for the expected value. So make sure the expected is the actual object returned from get in the loop.







                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited Jul 17 '16 at 13:29

























                    answered Jul 15 '14 at 18:15









                    Erik HellerenErik Helleren

                    84177




                    84177








                    • 14





                      Your two examples behave differently. You'd have to loop on worked to get the same semantics.

                      – CurtainDog
                      Oct 13 '14 at 20:32








                    • 4





                      I think you should initialize the value inside the AtomicReference constructor, otherwise another thread may still see the value null before you call shared.set. (Unless shared.set is run in a static initializer.)

                      – Henno Vermeulen
                      May 20 '15 at 9:35






                    • 6





                      In your second example, you should as of Java 8 use something like: shared.updateAndGet( (x) -> (x+"lets add something")); ... which will repeatedly call the .compareAndSet until it works. That is equivalent to the synchronized block which would always succeed. You need to ensure that the lambda you pass in is side-effect-free though because it may be called multiple times.

                      – Tom Dibble
                      Dec 9 '15 at 17:02













                    • @CurtainDog Loop to hope that shared might become prevValue again? Good luck :)

                      – Ivan Balashov
                      Jul 14 '16 at 6:52






                    • 2





                      There is not need to make volatile String sharedValue. The synchronized(lock) is good enough to establish the happen before the relationship.

                      – Jai Pandit
                      Jul 20 '17 at 5:26














                    • 14





                      Your two examples behave differently. You'd have to loop on worked to get the same semantics.

                      – CurtainDog
                      Oct 13 '14 at 20:32








                    • 4





                      I think you should initialize the value inside the AtomicReference constructor, otherwise another thread may still see the value null before you call shared.set. (Unless shared.set is run in a static initializer.)

                      – Henno Vermeulen
                      May 20 '15 at 9:35






                    • 6





                      In your second example, you should as of Java 8 use something like: shared.updateAndGet( (x) -> (x+"lets add something")); ... which will repeatedly call the .compareAndSet until it works. That is equivalent to the synchronized block which would always succeed. You need to ensure that the lambda you pass in is side-effect-free though because it may be called multiple times.

                      – Tom Dibble
                      Dec 9 '15 at 17:02













                    • @CurtainDog Loop to hope that shared might become prevValue again? Good luck :)

                      – Ivan Balashov
                      Jul 14 '16 at 6:52






                    • 2





                      There is not need to make volatile String sharedValue. The synchronized(lock) is good enough to establish the happen before the relationship.

                      – Jai Pandit
                      Jul 20 '17 at 5:26








                    14




                    14





                    Your two examples behave differently. You'd have to loop on worked to get the same semantics.

                    – CurtainDog
                    Oct 13 '14 at 20:32







                    Your two examples behave differently. You'd have to loop on worked to get the same semantics.

                    – CurtainDog
                    Oct 13 '14 at 20:32






                    4




                    4





                    I think you should initialize the value inside the AtomicReference constructor, otherwise another thread may still see the value null before you call shared.set. (Unless shared.set is run in a static initializer.)

                    – Henno Vermeulen
                    May 20 '15 at 9:35





                    I think you should initialize the value inside the AtomicReference constructor, otherwise another thread may still see the value null before you call shared.set. (Unless shared.set is run in a static initializer.)

                    – Henno Vermeulen
                    May 20 '15 at 9:35




                    6




                    6





                    In your second example, you should as of Java 8 use something like: shared.updateAndGet( (x) -> (x+"lets add something")); ... which will repeatedly call the .compareAndSet until it works. That is equivalent to the synchronized block which would always succeed. You need to ensure that the lambda you pass in is side-effect-free though because it may be called multiple times.

                    – Tom Dibble
                    Dec 9 '15 at 17:02







                    In your second example, you should as of Java 8 use something like: shared.updateAndGet( (x) -> (x+"lets add something")); ... which will repeatedly call the .compareAndSet until it works. That is equivalent to the synchronized block which would always succeed. You need to ensure that the lambda you pass in is side-effect-free though because it may be called multiple times.

                    – Tom Dibble
                    Dec 9 '15 at 17:02















                    @CurtainDog Loop to hope that shared might become prevValue again? Good luck :)

                    – Ivan Balashov
                    Jul 14 '16 at 6:52





                    @CurtainDog Loop to hope that shared might become prevValue again? Good luck :)

                    – Ivan Balashov
                    Jul 14 '16 at 6:52




                    2




                    2





                    There is not need to make volatile String sharedValue. The synchronized(lock) is good enough to establish the happen before the relationship.

                    – Jai Pandit
                    Jul 20 '17 at 5:26





                    There is not need to make volatile String sharedValue. The synchronized(lock) is good enough to establish the happen before the relationship.

                    – Jai Pandit
                    Jul 20 '17 at 5:26











                    25














                    Here is a use case for AtomicReference:



                    Consider this class that acts as a number range, and uses individual AtmomicInteger variables to maintain lower and upper number bounds.



                    public class NumberRange {
                    // INVARIANT: lower <= upper
                    private final AtomicInteger lower = new AtomicInteger(0);
                    private final AtomicInteger upper = new AtomicInteger(0);

                    public void setLower(int i) {
                    // Warning -- unsafe check-then-act
                    if (i > upper.get())
                    throw new IllegalArgumentException(
                    "can't set lower to " + i + " > upper");
                    lower.set(i);
                    }

                    public void setUpper(int i) {
                    // Warning -- unsafe check-then-act
                    if (i < lower.get())
                    throw new IllegalArgumentException(
                    "can't set upper to " + i + " < lower");
                    upper.set(i);
                    }

                    public boolean isInRange(int i) {
                    return (i >= lower.get() && i <= upper.get());
                    }
                    }


                    Both setLower and setUpper are check-then-act sequences, but they do not use sufficient locking to make them atomic. If the number range holds (0, 10), and one thread calls setLower(5) while another thread calls setUpper(4), with some unlucky timing both will pass the checks in the setters and both modifications will be applied. The result is that the range now holds (5, 4)an invalid state. So while the underlying AtomicIntegers are thread-safe, the composite class is not. This can be fixed by using a AtomicReference instead of using individual AtomicIntegers for upper and lower bounds.



                    public class CasNumberRange {
                    //Immutable
                    private static class IntPair {
                    final int lower; // Invariant: lower <= upper
                    final int upper;
                    ...
                    }
                    private final AtomicReference<IntPair> values =
                    new AtomicReference<IntPair>(new IntPair(0, 0));

                    public int getLower() { return values.get().lower; }
                    public int getUpper() { return values.get().upper; }

                    public void setLower(int i) {
                    while (true) {
                    IntPair oldv = values.get();
                    if (i > oldv.upper)
                    throw new IllegalArgumentException(
                    "Can't set lower to " + i + " > upper");
                    IntPair newv = new IntPair(i, oldv.upper);
                    if (values.compareAndSet(oldv, newv))
                    return;
                    }
                    }
                    // similarly for setUpper
                    }





                    share|improve this answer



















                    • 1





                      This article is similar to your answer, but goes deep to more complicated things. It's interesting! ibm.com/developerworks/java/library/j-jtp04186

                      – LppEdd
                      Oct 8 '18 at 17:32
















                    25














                    Here is a use case for AtomicReference:



                    Consider this class that acts as a number range, and uses individual AtmomicInteger variables to maintain lower and upper number bounds.



                    public class NumberRange {
                    // INVARIANT: lower <= upper
                    private final AtomicInteger lower = new AtomicInteger(0);
                    private final AtomicInteger upper = new AtomicInteger(0);

                    public void setLower(int i) {
                    // Warning -- unsafe check-then-act
                    if (i > upper.get())
                    throw new IllegalArgumentException(
                    "can't set lower to " + i + " > upper");
                    lower.set(i);
                    }

                    public void setUpper(int i) {
                    // Warning -- unsafe check-then-act
                    if (i < lower.get())
                    throw new IllegalArgumentException(
                    "can't set upper to " + i + " < lower");
                    upper.set(i);
                    }

                    public boolean isInRange(int i) {
                    return (i >= lower.get() && i <= upper.get());
                    }
                    }


                    Both setLower and setUpper are check-then-act sequences, but they do not use sufficient locking to make them atomic. If the number range holds (0, 10), and one thread calls setLower(5) while another thread calls setUpper(4), with some unlucky timing both will pass the checks in the setters and both modifications will be applied. The result is that the range now holds (5, 4)an invalid state. So while the underlying AtomicIntegers are thread-safe, the composite class is not. This can be fixed by using a AtomicReference instead of using individual AtomicIntegers for upper and lower bounds.



                    public class CasNumberRange {
                    //Immutable
                    private static class IntPair {
                    final int lower; // Invariant: lower <= upper
                    final int upper;
                    ...
                    }
                    private final AtomicReference<IntPair> values =
                    new AtomicReference<IntPair>(new IntPair(0, 0));

                    public int getLower() { return values.get().lower; }
                    public int getUpper() { return values.get().upper; }

                    public void setLower(int i) {
                    while (true) {
                    IntPair oldv = values.get();
                    if (i > oldv.upper)
                    throw new IllegalArgumentException(
                    "Can't set lower to " + i + " > upper");
                    IntPair newv = new IntPair(i, oldv.upper);
                    if (values.compareAndSet(oldv, newv))
                    return;
                    }
                    }
                    // similarly for setUpper
                    }





                    share|improve this answer



















                    • 1





                      This article is similar to your answer, but goes deep to more complicated things. It's interesting! ibm.com/developerworks/java/library/j-jtp04186

                      – LppEdd
                      Oct 8 '18 at 17:32














                    25












                    25








                    25







                    Here is a use case for AtomicReference:



                    Consider this class that acts as a number range, and uses individual AtmomicInteger variables to maintain lower and upper number bounds.



                    public class NumberRange {
                    // INVARIANT: lower <= upper
                    private final AtomicInteger lower = new AtomicInteger(0);
                    private final AtomicInteger upper = new AtomicInteger(0);

                    public void setLower(int i) {
                    // Warning -- unsafe check-then-act
                    if (i > upper.get())
                    throw new IllegalArgumentException(
                    "can't set lower to " + i + " > upper");
                    lower.set(i);
                    }

                    public void setUpper(int i) {
                    // Warning -- unsafe check-then-act
                    if (i < lower.get())
                    throw new IllegalArgumentException(
                    "can't set upper to " + i + " < lower");
                    upper.set(i);
                    }

                    public boolean isInRange(int i) {
                    return (i >= lower.get() && i <= upper.get());
                    }
                    }


                    Both setLower and setUpper are check-then-act sequences, but they do not use sufficient locking to make them atomic. If the number range holds (0, 10), and one thread calls setLower(5) while another thread calls setUpper(4), with some unlucky timing both will pass the checks in the setters and both modifications will be applied. The result is that the range now holds (5, 4)an invalid state. So while the underlying AtomicIntegers are thread-safe, the composite class is not. This can be fixed by using a AtomicReference instead of using individual AtomicIntegers for upper and lower bounds.



                    public class CasNumberRange {
                    //Immutable
                    private static class IntPair {
                    final int lower; // Invariant: lower <= upper
                    final int upper;
                    ...
                    }
                    private final AtomicReference<IntPair> values =
                    new AtomicReference<IntPair>(new IntPair(0, 0));

                    public int getLower() { return values.get().lower; }
                    public int getUpper() { return values.get().upper; }

                    public void setLower(int i) {
                    while (true) {
                    IntPair oldv = values.get();
                    if (i > oldv.upper)
                    throw new IllegalArgumentException(
                    "Can't set lower to " + i + " > upper");
                    IntPair newv = new IntPair(i, oldv.upper);
                    if (values.compareAndSet(oldv, newv))
                    return;
                    }
                    }
                    // similarly for setUpper
                    }





                    share|improve this answer













                    Here is a use case for AtomicReference:



                    Consider this class that acts as a number range, and uses individual AtmomicInteger variables to maintain lower and upper number bounds.



                    public class NumberRange {
                    // INVARIANT: lower <= upper
                    private final AtomicInteger lower = new AtomicInteger(0);
                    private final AtomicInteger upper = new AtomicInteger(0);

                    public void setLower(int i) {
                    // Warning -- unsafe check-then-act
                    if (i > upper.get())
                    throw new IllegalArgumentException(
                    "can't set lower to " + i + " > upper");
                    lower.set(i);
                    }

                    public void setUpper(int i) {
                    // Warning -- unsafe check-then-act
                    if (i < lower.get())
                    throw new IllegalArgumentException(
                    "can't set upper to " + i + " < lower");
                    upper.set(i);
                    }

                    public boolean isInRange(int i) {
                    return (i >= lower.get() && i <= upper.get());
                    }
                    }


                    Both setLower and setUpper are check-then-act sequences, but they do not use sufficient locking to make them atomic. If the number range holds (0, 10), and one thread calls setLower(5) while another thread calls setUpper(4), with some unlucky timing both will pass the checks in the setters and both modifications will be applied. The result is that the range now holds (5, 4)an invalid state. So while the underlying AtomicIntegers are thread-safe, the composite class is not. This can be fixed by using a AtomicReference instead of using individual AtomicIntegers for upper and lower bounds.



                    public class CasNumberRange {
                    //Immutable
                    private static class IntPair {
                    final int lower; // Invariant: lower <= upper
                    final int upper;
                    ...
                    }
                    private final AtomicReference<IntPair> values =
                    new AtomicReference<IntPair>(new IntPair(0, 0));

                    public int getLower() { return values.get().lower; }
                    public int getUpper() { return values.get().upper; }

                    public void setLower(int i) {
                    while (true) {
                    IntPair oldv = values.get();
                    if (i > oldv.upper)
                    throw new IllegalArgumentException(
                    "Can't set lower to " + i + " > upper");
                    IntPair newv = new IntPair(i, oldv.upper);
                    if (values.compareAndSet(oldv, newv))
                    return;
                    }
                    }
                    // similarly for setUpper
                    }






                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered May 29 '15 at 10:00









                    Binita BharatiBinita Bharati

                    1,4991614




                    1,4991614








                    • 1





                      This article is similar to your answer, but goes deep to more complicated things. It's interesting! ibm.com/developerworks/java/library/j-jtp04186

                      – LppEdd
                      Oct 8 '18 at 17:32














                    • 1





                      This article is similar to your answer, but goes deep to more complicated things. It's interesting! ibm.com/developerworks/java/library/j-jtp04186

                      – LppEdd
                      Oct 8 '18 at 17:32








                    1




                    1





                    This article is similar to your answer, but goes deep to more complicated things. It's interesting! ibm.com/developerworks/java/library/j-jtp04186

                    – LppEdd
                    Oct 8 '18 at 17:32





                    This article is similar to your answer, but goes deep to more complicated things. It's interesting! ibm.com/developerworks/java/library/j-jtp04186

                    – LppEdd
                    Oct 8 '18 at 17:32











                    18














                    You can use AtomicReference when applying optimistic locks. You have a shared object and you want to change it from more than 1 thread.




                    1. You can create a copy of the shared object

                    2. Modify the shared object

                    3. You need to check that the shared object is still the same as before - if yes, then update with the reference of the modified copy.


                    As other thread might have modified it and/can modify between these 2 steps. You need to do it in an atomic operation. this is where AtomicReference can help






                    share|improve this answer




























                      18














                      You can use AtomicReference when applying optimistic locks. You have a shared object and you want to change it from more than 1 thread.




                      1. You can create a copy of the shared object

                      2. Modify the shared object

                      3. You need to check that the shared object is still the same as before - if yes, then update with the reference of the modified copy.


                      As other thread might have modified it and/can modify between these 2 steps. You need to do it in an atomic operation. this is where AtomicReference can help






                      share|improve this answer


























                        18












                        18








                        18







                        You can use AtomicReference when applying optimistic locks. You have a shared object and you want to change it from more than 1 thread.




                        1. You can create a copy of the shared object

                        2. Modify the shared object

                        3. You need to check that the shared object is still the same as before - if yes, then update with the reference of the modified copy.


                        As other thread might have modified it and/can modify between these 2 steps. You need to do it in an atomic operation. this is where AtomicReference can help






                        share|improve this answer













                        You can use AtomicReference when applying optimistic locks. You have a shared object and you want to change it from more than 1 thread.




                        1. You can create a copy of the shared object

                        2. Modify the shared object

                        3. You need to check that the shared object is still the same as before - if yes, then update with the reference of the modified copy.


                        As other thread might have modified it and/can modify between these 2 steps. You need to do it in an atomic operation. this is where AtomicReference can help







                        share|improve this answer












                        share|improve this answer



                        share|improve this answer










                        answered Jun 12 '15 at 12:30









                        HamoriZHamoriZ

                        1,5411129




                        1,5411129























                            3














                            Here's a very simple use case and has nothing to do with thread safety.



                            To share an object between lambda invocations, the AtomicReference is an option:



                            public void doSomethingUsingLambdas() {

                            AtomicReference<YourObject> yourObjectRef = new AtomicReference<>();

                            soSomethingThatTakesALambda(() -> {
                            yourObjectRef.set(youObject);
                            });

                            soSomethingElseThatTakesALambda(() -> {
                            YourObject yourObject = yourObjectRef.get();
                            });
                            }


                            I'm not saying this is good design or anything (it's just a trivial example), but if you have have the case where you need to share an object between lambda invocations, the AtomicReference is an option.



                            In fact you can use any object that holds a reference, even a Collection that has only one item. However, the AtomicReference is a perfect fit.






                            share|improve this answer




























                              3














                              Here's a very simple use case and has nothing to do with thread safety.



                              To share an object between lambda invocations, the AtomicReference is an option:



                              public void doSomethingUsingLambdas() {

                              AtomicReference<YourObject> yourObjectRef = new AtomicReference<>();

                              soSomethingThatTakesALambda(() -> {
                              yourObjectRef.set(youObject);
                              });

                              soSomethingElseThatTakesALambda(() -> {
                              YourObject yourObject = yourObjectRef.get();
                              });
                              }


                              I'm not saying this is good design or anything (it's just a trivial example), but if you have have the case where you need to share an object between lambda invocations, the AtomicReference is an option.



                              In fact you can use any object that holds a reference, even a Collection that has only one item. However, the AtomicReference is a perfect fit.






                              share|improve this answer


























                                3












                                3








                                3







                                Here's a very simple use case and has nothing to do with thread safety.



                                To share an object between lambda invocations, the AtomicReference is an option:



                                public void doSomethingUsingLambdas() {

                                AtomicReference<YourObject> yourObjectRef = new AtomicReference<>();

                                soSomethingThatTakesALambda(() -> {
                                yourObjectRef.set(youObject);
                                });

                                soSomethingElseThatTakesALambda(() -> {
                                YourObject yourObject = yourObjectRef.get();
                                });
                                }


                                I'm not saying this is good design or anything (it's just a trivial example), but if you have have the case where you need to share an object between lambda invocations, the AtomicReference is an option.



                                In fact you can use any object that holds a reference, even a Collection that has only one item. However, the AtomicReference is a perfect fit.






                                share|improve this answer













                                Here's a very simple use case and has nothing to do with thread safety.



                                To share an object between lambda invocations, the AtomicReference is an option:



                                public void doSomethingUsingLambdas() {

                                AtomicReference<YourObject> yourObjectRef = new AtomicReference<>();

                                soSomethingThatTakesALambda(() -> {
                                yourObjectRef.set(youObject);
                                });

                                soSomethingElseThatTakesALambda(() -> {
                                YourObject yourObject = yourObjectRef.get();
                                });
                                }


                                I'm not saying this is good design or anything (it's just a trivial example), but if you have have the case where you need to share an object between lambda invocations, the AtomicReference is an option.



                                In fact you can use any object that holds a reference, even a Collection that has only one item. However, the AtomicReference is a perfect fit.







                                share|improve this answer












                                share|improve this answer



                                share|improve this answer










                                answered Apr 23 '18 at 9:00









                                Benny BottemaBenny Bottema

                                5,14284668




                                5,14284668























                                    3














                                    I won't talk much. Already my respected fellow friends have given their valuable input. The full fledged running code at the last of this blog should remove any confusion. It's about a movie seat booking small program in multi-threaded scenario.



                                    Some important elementary facts are as follows.
                                    1> Different threads can only contend for instance and static member variables in the heap space.
                                    2> Volatile read or write are completely atomic and serialized/happens before and only done from memory. By saying this I mean that any read will follow the previous write in memory. And any write will follow the previous read from memory. So any thread working with a volatile will always see the most up-to-date value.
                                    AtomicReference uses this property of volatile.



                                    Following are some of the source code of AtomicReference.
                                    AtomicReference refers to an object reference. This reference is a volatile member variable in the AtomicReference instance as below.



                                    private volatile V value;


                                    get() simply returns the latest value of the variable (as volatiles do in a "happens before" manner).



                                    public final V get()


                                    Following is the most important method of AtomicReference.



                                    public final boolean  compareAndSet(V expect, V update) {
                                    return unsafe.compareAndSwapObject(this, valueOffset, expect, update);
                                    }


                                    The compareAndSet(expect,update) method calls the compareAndSwapObject() method of the unsafe class of Java. This method call of unsafe invokes the native call, which invokes a single instruction to the processor. "expect" and "update" each reference an object.



                                    If and only if the AtomicReference instance member variable "value" refers to the same object is referred to by "expect", "update" is assigned to this instance variable now, and "true" is returned. Or else, false is returned. The whole thing is done atomically. No other thread can intercept in between.
                                    As this is a single processor operation (magic of modern computer architecture), it's often faster than using a synchronized block. But remember that when multiple variables need to be updated atomically, AtomicReference won't help.



                                    I would like to add a full fledged running code, which can be run in eclipse. It would clear many confusion. Here 22 users (MyTh threads) are trying to book 20 seats. Following is the code snippet followed by the full code.



                                    Code snippet where 22 users are trying to book 20 seats.



                                    for (int i = 0; i < 20; i++) {// 20 seats
                                    seats.add(new AtomicReference<Integer>());
                                    }
                                    Thread ths = new Thread[22];// 22 users
                                    for (int i = 0; i < ths.length; i++) {
                                    ths[i] = new MyTh(seats, i);
                                    ths[i].start();
                                    }


                                    Following is the full running code.



                                    import java.util.ArrayList;
                                    import java.util.List;
                                    import java.util.concurrent.ThreadLocalRandom;
                                    import java.util.concurrent.atomic.AtomicInteger;
                                    import java.util.concurrent.atomic.AtomicReference;

                                    public class Solution {

                                    static List<AtomicReference<Integer>> seats;// Movie seats numbered as per
                                    // list index

                                    public static void main(String args) throws InterruptedException {
                                    // TODO Auto-generated method stub
                                    seats = new ArrayList<>();
                                    for (int i = 0; i < 20; i++) {// 20 seats
                                    seats.add(new AtomicReference<Integer>());
                                    }
                                    Thread ths = new Thread[22];// 22 users
                                    for (int i = 0; i < ths.length; i++) {
                                    ths[i] = new MyTh(seats, i);
                                    ths[i].start();
                                    }
                                    for (Thread t : ths) {
                                    t.join();
                                    }
                                    for (AtomicReference<Integer> seat : seats) {
                                    System.out.print(" " + seat.get());
                                    }
                                    }

                                    /**
                                    * id is the id of the user
                                    *
                                    * @author sankbane
                                    *
                                    */
                                    static class MyTh extends Thread {// each thread is a user
                                    static AtomicInteger full = new AtomicInteger(0);
                                    List<AtomicReference<Integer>> l;//seats
                                    int id;//id of the users
                                    int seats;

                                    public MyTh(List<AtomicReference<Integer>> list, int userId) {
                                    l = list;
                                    this.id = userId;
                                    seats = list.size();
                                    }

                                    @Override
                                    public void run() {
                                    boolean reserved = false;
                                    try {
                                    while (!reserved && full.get() < seats) {
                                    Thread.sleep(50);
                                    int r = ThreadLocalRandom.current().nextInt(0, seats);// excludes
                                    // seats
                                    //
                                    AtomicReference<Integer> el = l.get(r);
                                    reserved = el.compareAndSet(null, id);// null means no user
                                    // has reserved this
                                    // seat
                                    if (reserved)
                                    full.getAndIncrement();
                                    }
                                    if (!reserved && full.get() == seats)
                                    System.out.println("user " + id + " did not get a seat");
                                    } catch (InterruptedException ie) {
                                    // log it
                                    }
                                    }
                                    }

                                    }





                                    share|improve this answer






























                                      3














                                      I won't talk much. Already my respected fellow friends have given their valuable input. The full fledged running code at the last of this blog should remove any confusion. It's about a movie seat booking small program in multi-threaded scenario.



                                      Some important elementary facts are as follows.
                                      1> Different threads can only contend for instance and static member variables in the heap space.
                                      2> Volatile read or write are completely atomic and serialized/happens before and only done from memory. By saying this I mean that any read will follow the previous write in memory. And any write will follow the previous read from memory. So any thread working with a volatile will always see the most up-to-date value.
                                      AtomicReference uses this property of volatile.



                                      Following are some of the source code of AtomicReference.
                                      AtomicReference refers to an object reference. This reference is a volatile member variable in the AtomicReference instance as below.



                                      private volatile V value;


                                      get() simply returns the latest value of the variable (as volatiles do in a "happens before" manner).



                                      public final V get()


                                      Following is the most important method of AtomicReference.



                                      public final boolean  compareAndSet(V expect, V update) {
                                      return unsafe.compareAndSwapObject(this, valueOffset, expect, update);
                                      }


                                      The compareAndSet(expect,update) method calls the compareAndSwapObject() method of the unsafe class of Java. This method call of unsafe invokes the native call, which invokes a single instruction to the processor. "expect" and "update" each reference an object.



                                      If and only if the AtomicReference instance member variable "value" refers to the same object is referred to by "expect", "update" is assigned to this instance variable now, and "true" is returned. Or else, false is returned. The whole thing is done atomically. No other thread can intercept in between.
                                      As this is a single processor operation (magic of modern computer architecture), it's often faster than using a synchronized block. But remember that when multiple variables need to be updated atomically, AtomicReference won't help.



                                      I would like to add a full fledged running code, which can be run in eclipse. It would clear many confusion. Here 22 users (MyTh threads) are trying to book 20 seats. Following is the code snippet followed by the full code.



                                      Code snippet where 22 users are trying to book 20 seats.



                                      for (int i = 0; i < 20; i++) {// 20 seats
                                      seats.add(new AtomicReference<Integer>());
                                      }
                                      Thread ths = new Thread[22];// 22 users
                                      for (int i = 0; i < ths.length; i++) {
                                      ths[i] = new MyTh(seats, i);
                                      ths[i].start();
                                      }


                                      Following is the full running code.



                                      import java.util.ArrayList;
                                      import java.util.List;
                                      import java.util.concurrent.ThreadLocalRandom;
                                      import java.util.concurrent.atomic.AtomicInteger;
                                      import java.util.concurrent.atomic.AtomicReference;

                                      public class Solution {

                                      static List<AtomicReference<Integer>> seats;// Movie seats numbered as per
                                      // list index

                                      public static void main(String args) throws InterruptedException {
                                      // TODO Auto-generated method stub
                                      seats = new ArrayList<>();
                                      for (int i = 0; i < 20; i++) {// 20 seats
                                      seats.add(new AtomicReference<Integer>());
                                      }
                                      Thread ths = new Thread[22];// 22 users
                                      for (int i = 0; i < ths.length; i++) {
                                      ths[i] = new MyTh(seats, i);
                                      ths[i].start();
                                      }
                                      for (Thread t : ths) {
                                      t.join();
                                      }
                                      for (AtomicReference<Integer> seat : seats) {
                                      System.out.print(" " + seat.get());
                                      }
                                      }

                                      /**
                                      * id is the id of the user
                                      *
                                      * @author sankbane
                                      *
                                      */
                                      static class MyTh extends Thread {// each thread is a user
                                      static AtomicInteger full = new AtomicInteger(0);
                                      List<AtomicReference<Integer>> l;//seats
                                      int id;//id of the users
                                      int seats;

                                      public MyTh(List<AtomicReference<Integer>> list, int userId) {
                                      l = list;
                                      this.id = userId;
                                      seats = list.size();
                                      }

                                      @Override
                                      public void run() {
                                      boolean reserved = false;
                                      try {
                                      while (!reserved && full.get() < seats) {
                                      Thread.sleep(50);
                                      int r = ThreadLocalRandom.current().nextInt(0, seats);// excludes
                                      // seats
                                      //
                                      AtomicReference<Integer> el = l.get(r);
                                      reserved = el.compareAndSet(null, id);// null means no user
                                      // has reserved this
                                      // seat
                                      if (reserved)
                                      full.getAndIncrement();
                                      }
                                      if (!reserved && full.get() == seats)
                                      System.out.println("user " + id + " did not get a seat");
                                      } catch (InterruptedException ie) {
                                      // log it
                                      }
                                      }
                                      }

                                      }





                                      share|improve this answer




























                                        3












                                        3








                                        3







                                        I won't talk much. Already my respected fellow friends have given their valuable input. The full fledged running code at the last of this blog should remove any confusion. It's about a movie seat booking small program in multi-threaded scenario.



                                        Some important elementary facts are as follows.
                                        1> Different threads can only contend for instance and static member variables in the heap space.
                                        2> Volatile read or write are completely atomic and serialized/happens before and only done from memory. By saying this I mean that any read will follow the previous write in memory. And any write will follow the previous read from memory. So any thread working with a volatile will always see the most up-to-date value.
                                        AtomicReference uses this property of volatile.



                                        Following are some of the source code of AtomicReference.
                                        AtomicReference refers to an object reference. This reference is a volatile member variable in the AtomicReference instance as below.



                                        private volatile V value;


                                        get() simply returns the latest value of the variable (as volatiles do in a "happens before" manner).



                                        public final V get()


                                        Following is the most important method of AtomicReference.



                                        public final boolean  compareAndSet(V expect, V update) {
                                        return unsafe.compareAndSwapObject(this, valueOffset, expect, update);
                                        }


                                        The compareAndSet(expect,update) method calls the compareAndSwapObject() method of the unsafe class of Java. This method call of unsafe invokes the native call, which invokes a single instruction to the processor. "expect" and "update" each reference an object.



                                        If and only if the AtomicReference instance member variable "value" refers to the same object is referred to by "expect", "update" is assigned to this instance variable now, and "true" is returned. Or else, false is returned. The whole thing is done atomically. No other thread can intercept in between.
                                        As this is a single processor operation (magic of modern computer architecture), it's often faster than using a synchronized block. But remember that when multiple variables need to be updated atomically, AtomicReference won't help.



                                        I would like to add a full fledged running code, which can be run in eclipse. It would clear many confusion. Here 22 users (MyTh threads) are trying to book 20 seats. Following is the code snippet followed by the full code.



                                        Code snippet where 22 users are trying to book 20 seats.



                                        for (int i = 0; i < 20; i++) {// 20 seats
                                        seats.add(new AtomicReference<Integer>());
                                        }
                                        Thread ths = new Thread[22];// 22 users
                                        for (int i = 0; i < ths.length; i++) {
                                        ths[i] = new MyTh(seats, i);
                                        ths[i].start();
                                        }


                                        Following is the full running code.



                                        import java.util.ArrayList;
                                        import java.util.List;
                                        import java.util.concurrent.ThreadLocalRandom;
                                        import java.util.concurrent.atomic.AtomicInteger;
                                        import java.util.concurrent.atomic.AtomicReference;

                                        public class Solution {

                                        static List<AtomicReference<Integer>> seats;// Movie seats numbered as per
                                        // list index

                                        public static void main(String args) throws InterruptedException {
                                        // TODO Auto-generated method stub
                                        seats = new ArrayList<>();
                                        for (int i = 0; i < 20; i++) {// 20 seats
                                        seats.add(new AtomicReference<Integer>());
                                        }
                                        Thread ths = new Thread[22];// 22 users
                                        for (int i = 0; i < ths.length; i++) {
                                        ths[i] = new MyTh(seats, i);
                                        ths[i].start();
                                        }
                                        for (Thread t : ths) {
                                        t.join();
                                        }
                                        for (AtomicReference<Integer> seat : seats) {
                                        System.out.print(" " + seat.get());
                                        }
                                        }

                                        /**
                                        * id is the id of the user
                                        *
                                        * @author sankbane
                                        *
                                        */
                                        static class MyTh extends Thread {// each thread is a user
                                        static AtomicInteger full = new AtomicInteger(0);
                                        List<AtomicReference<Integer>> l;//seats
                                        int id;//id of the users
                                        int seats;

                                        public MyTh(List<AtomicReference<Integer>> list, int userId) {
                                        l = list;
                                        this.id = userId;
                                        seats = list.size();
                                        }

                                        @Override
                                        public void run() {
                                        boolean reserved = false;
                                        try {
                                        while (!reserved && full.get() < seats) {
                                        Thread.sleep(50);
                                        int r = ThreadLocalRandom.current().nextInt(0, seats);// excludes
                                        // seats
                                        //
                                        AtomicReference<Integer> el = l.get(r);
                                        reserved = el.compareAndSet(null, id);// null means no user
                                        // has reserved this
                                        // seat
                                        if (reserved)
                                        full.getAndIncrement();
                                        }
                                        if (!reserved && full.get() == seats)
                                        System.out.println("user " + id + " did not get a seat");
                                        } catch (InterruptedException ie) {
                                        // log it
                                        }
                                        }
                                        }

                                        }





                                        share|improve this answer















                                        I won't talk much. Already my respected fellow friends have given their valuable input. The full fledged running code at the last of this blog should remove any confusion. It's about a movie seat booking small program in multi-threaded scenario.



                                        Some important elementary facts are as follows.
                                        1> Different threads can only contend for instance and static member variables in the heap space.
                                        2> Volatile read or write are completely atomic and serialized/happens before and only done from memory. By saying this I mean that any read will follow the previous write in memory. And any write will follow the previous read from memory. So any thread working with a volatile will always see the most up-to-date value.
                                        AtomicReference uses this property of volatile.



                                        Following are some of the source code of AtomicReference.
                                        AtomicReference refers to an object reference. This reference is a volatile member variable in the AtomicReference instance as below.



                                        private volatile V value;


                                        get() simply returns the latest value of the variable (as volatiles do in a "happens before" manner).



                                        public final V get()


                                        Following is the most important method of AtomicReference.



                                        public final boolean  compareAndSet(V expect, V update) {
                                        return unsafe.compareAndSwapObject(this, valueOffset, expect, update);
                                        }


                                        The compareAndSet(expect,update) method calls the compareAndSwapObject() method of the unsafe class of Java. This method call of unsafe invokes the native call, which invokes a single instruction to the processor. "expect" and "update" each reference an object.



                                        If and only if the AtomicReference instance member variable "value" refers to the same object is referred to by "expect", "update" is assigned to this instance variable now, and "true" is returned. Or else, false is returned. The whole thing is done atomically. No other thread can intercept in between.
                                        As this is a single processor operation (magic of modern computer architecture), it's often faster than using a synchronized block. But remember that when multiple variables need to be updated atomically, AtomicReference won't help.



                                        I would like to add a full fledged running code, which can be run in eclipse. It would clear many confusion. Here 22 users (MyTh threads) are trying to book 20 seats. Following is the code snippet followed by the full code.



                                        Code snippet where 22 users are trying to book 20 seats.



                                        for (int i = 0; i < 20; i++) {// 20 seats
                                        seats.add(new AtomicReference<Integer>());
                                        }
                                        Thread ths = new Thread[22];// 22 users
                                        for (int i = 0; i < ths.length; i++) {
                                        ths[i] = new MyTh(seats, i);
                                        ths[i].start();
                                        }


                                        Following is the full running code.



                                        import java.util.ArrayList;
                                        import java.util.List;
                                        import java.util.concurrent.ThreadLocalRandom;
                                        import java.util.concurrent.atomic.AtomicInteger;
                                        import java.util.concurrent.atomic.AtomicReference;

                                        public class Solution {

                                        static List<AtomicReference<Integer>> seats;// Movie seats numbered as per
                                        // list index

                                        public static void main(String args) throws InterruptedException {
                                        // TODO Auto-generated method stub
                                        seats = new ArrayList<>();
                                        for (int i = 0; i < 20; i++) {// 20 seats
                                        seats.add(new AtomicReference<Integer>());
                                        }
                                        Thread ths = new Thread[22];// 22 users
                                        for (int i = 0; i < ths.length; i++) {
                                        ths[i] = new MyTh(seats, i);
                                        ths[i].start();
                                        }
                                        for (Thread t : ths) {
                                        t.join();
                                        }
                                        for (AtomicReference<Integer> seat : seats) {
                                        System.out.print(" " + seat.get());
                                        }
                                        }

                                        /**
                                        * id is the id of the user
                                        *
                                        * @author sankbane
                                        *
                                        */
                                        static class MyTh extends Thread {// each thread is a user
                                        static AtomicInteger full = new AtomicInteger(0);
                                        List<AtomicReference<Integer>> l;//seats
                                        int id;//id of the users
                                        int seats;

                                        public MyTh(List<AtomicReference<Integer>> list, int userId) {
                                        l = list;
                                        this.id = userId;
                                        seats = list.size();
                                        }

                                        @Override
                                        public void run() {
                                        boolean reserved = false;
                                        try {
                                        while (!reserved && full.get() < seats) {
                                        Thread.sleep(50);
                                        int r = ThreadLocalRandom.current().nextInt(0, seats);// excludes
                                        // seats
                                        //
                                        AtomicReference<Integer> el = l.get(r);
                                        reserved = el.compareAndSet(null, id);// null means no user
                                        // has reserved this
                                        // seat
                                        if (reserved)
                                        full.getAndIncrement();
                                        }
                                        if (!reserved && full.get() == seats)
                                        System.out.println("user " + id + " did not get a seat");
                                        } catch (InterruptedException ie) {
                                        // log it
                                        }
                                        }
                                        }

                                        }






                                        share|improve this answer














                                        share|improve this answer



                                        share|improve this answer








                                        edited May 31 '18 at 6:41

























                                        answered May 31 '18 at 5:54









                                        sankar banerjeesankar banerjee

                                        413




                                        413























                                            2















                                            When do we use AtomicReference?




                                            AtomicReference is flexible way to update the variable value atomically without use of synchronization.



                                            AtomicReference support lock-free thread-safe programming on single variables.



                                            There are multiple ways of achieving Thread safety with high level concurrent API. Atomic variables is one of the multiple options.



                                            Lock objects support locking idioms that simplify many concurrent applications.



                                            Executors define a high-level API for launching and managing threads. Executor implementations provided by java.util.concurrent provide thread pool management suitable for large-scale applications.



                                            Concurrent collections make it easier to manage large collections of data, and can greatly reduce the need for synchronization.



                                            Atomic variables have features that minimize synchronization and help avoid memory consistency errors.




                                            Provide a simple example where AtomicReference should be used.




                                            Sample code with AtomicReference:



                                            String initialReference = "value 1";

                                            AtomicReference<String> someRef =
                                            new AtomicReference<String>(initialReference);

                                            String newReference = "value 2";
                                            boolean exchanged = someRef.compareAndSet(initialReference, newReference);
                                            System.out.println("exchanged: " + exchanged);



                                            Is it needed to create objects in all multithreaded programs?




                                            You don't have to use AtomicReference in all multi threaded programs.



                                            If you want to guard a single variable, use AtomicReference. If you want to guard a code block, use other constructs like Lock /synchronized etc.






                                            share|improve this answer






























                                              2















                                              When do we use AtomicReference?




                                              AtomicReference is flexible way to update the variable value atomically without use of synchronization.



                                              AtomicReference support lock-free thread-safe programming on single variables.



                                              There are multiple ways of achieving Thread safety with high level concurrent API. Atomic variables is one of the multiple options.



                                              Lock objects support locking idioms that simplify many concurrent applications.



                                              Executors define a high-level API for launching and managing threads. Executor implementations provided by java.util.concurrent provide thread pool management suitable for large-scale applications.



                                              Concurrent collections make it easier to manage large collections of data, and can greatly reduce the need for synchronization.



                                              Atomic variables have features that minimize synchronization and help avoid memory consistency errors.




                                              Provide a simple example where AtomicReference should be used.




                                              Sample code with AtomicReference:



                                              String initialReference = "value 1";

                                              AtomicReference<String> someRef =
                                              new AtomicReference<String>(initialReference);

                                              String newReference = "value 2";
                                              boolean exchanged = someRef.compareAndSet(initialReference, newReference);
                                              System.out.println("exchanged: " + exchanged);



                                              Is it needed to create objects in all multithreaded programs?




                                              You don't have to use AtomicReference in all multi threaded programs.



                                              If you want to guard a single variable, use AtomicReference. If you want to guard a code block, use other constructs like Lock /synchronized etc.






                                              share|improve this answer




























                                                2












                                                2








                                                2








                                                When do we use AtomicReference?




                                                AtomicReference is flexible way to update the variable value atomically without use of synchronization.



                                                AtomicReference support lock-free thread-safe programming on single variables.



                                                There are multiple ways of achieving Thread safety with high level concurrent API. Atomic variables is one of the multiple options.



                                                Lock objects support locking idioms that simplify many concurrent applications.



                                                Executors define a high-level API for launching and managing threads. Executor implementations provided by java.util.concurrent provide thread pool management suitable for large-scale applications.



                                                Concurrent collections make it easier to manage large collections of data, and can greatly reduce the need for synchronization.



                                                Atomic variables have features that minimize synchronization and help avoid memory consistency errors.




                                                Provide a simple example where AtomicReference should be used.




                                                Sample code with AtomicReference:



                                                String initialReference = "value 1";

                                                AtomicReference<String> someRef =
                                                new AtomicReference<String>(initialReference);

                                                String newReference = "value 2";
                                                boolean exchanged = someRef.compareAndSet(initialReference, newReference);
                                                System.out.println("exchanged: " + exchanged);



                                                Is it needed to create objects in all multithreaded programs?




                                                You don't have to use AtomicReference in all multi threaded programs.



                                                If you want to guard a single variable, use AtomicReference. If you want to guard a code block, use other constructs like Lock /synchronized etc.






                                                share|improve this answer
















                                                When do we use AtomicReference?




                                                AtomicReference is flexible way to update the variable value atomically without use of synchronization.



                                                AtomicReference support lock-free thread-safe programming on single variables.



                                                There are multiple ways of achieving Thread safety with high level concurrent API. Atomic variables is one of the multiple options.



                                                Lock objects support locking idioms that simplify many concurrent applications.



                                                Executors define a high-level API for launching and managing threads. Executor implementations provided by java.util.concurrent provide thread pool management suitable for large-scale applications.



                                                Concurrent collections make it easier to manage large collections of data, and can greatly reduce the need for synchronization.



                                                Atomic variables have features that minimize synchronization and help avoid memory consistency errors.




                                                Provide a simple example where AtomicReference should be used.




                                                Sample code with AtomicReference:



                                                String initialReference = "value 1";

                                                AtomicReference<String> someRef =
                                                new AtomicReference<String>(initialReference);

                                                String newReference = "value 2";
                                                boolean exchanged = someRef.compareAndSet(initialReference, newReference);
                                                System.out.println("exchanged: " + exchanged);



                                                Is it needed to create objects in all multithreaded programs?




                                                You don't have to use AtomicReference in all multi threaded programs.



                                                If you want to guard a single variable, use AtomicReference. If you want to guard a code block, use other constructs like Lock /synchronized etc.







                                                share|improve this answer














                                                share|improve this answer



                                                share|improve this answer








                                                edited Jan 7 '18 at 7:40

























                                                answered May 20 '16 at 6:05









                                                Ravindra babuRavindra babu

                                                29.7k5161136




                                                29.7k5161136























                                                    -1














                                                    Another simple example is to do a safe-thread modification in a session object.



                                                    public PlayerScore getHighScore() {
                                                    ServletContext ctx = getServletConfig().getServletContext();
                                                    AtomicReference<PlayerScore> holder
                                                    = (AtomicReference<PlayerScore>) ctx.getAttribute("highScore");
                                                    return holder.get();
                                                    }

                                                    public void updateHighScore(PlayerScore newScore) {
                                                    ServletContext ctx = getServletConfig().getServletContext();
                                                    AtomicReference<PlayerScore> holder
                                                    = (AtomicReference<PlayerScore>) ctx.getAttribute("highScore");
                                                    while (true) {
                                                    HighScore old = holder.get();
                                                    if (old.score >= newScore.score)
                                                    break;
                                                    else if (holder.compareAndSet(old, newScore))
                                                    break;
                                                    }
                                                    }


                                                    Source: http://www.ibm.com/developerworks/library/j-jtp09238/index.html






                                                    share|improve this answer




























                                                      -1














                                                      Another simple example is to do a safe-thread modification in a session object.



                                                      public PlayerScore getHighScore() {
                                                      ServletContext ctx = getServletConfig().getServletContext();
                                                      AtomicReference<PlayerScore> holder
                                                      = (AtomicReference<PlayerScore>) ctx.getAttribute("highScore");
                                                      return holder.get();
                                                      }

                                                      public void updateHighScore(PlayerScore newScore) {
                                                      ServletContext ctx = getServletConfig().getServletContext();
                                                      AtomicReference<PlayerScore> holder
                                                      = (AtomicReference<PlayerScore>) ctx.getAttribute("highScore");
                                                      while (true) {
                                                      HighScore old = holder.get();
                                                      if (old.score >= newScore.score)
                                                      break;
                                                      else if (holder.compareAndSet(old, newScore))
                                                      break;
                                                      }
                                                      }


                                                      Source: http://www.ibm.com/developerworks/library/j-jtp09238/index.html






                                                      share|improve this answer


























                                                        -1












                                                        -1








                                                        -1







                                                        Another simple example is to do a safe-thread modification in a session object.



                                                        public PlayerScore getHighScore() {
                                                        ServletContext ctx = getServletConfig().getServletContext();
                                                        AtomicReference<PlayerScore> holder
                                                        = (AtomicReference<PlayerScore>) ctx.getAttribute("highScore");
                                                        return holder.get();
                                                        }

                                                        public void updateHighScore(PlayerScore newScore) {
                                                        ServletContext ctx = getServletConfig().getServletContext();
                                                        AtomicReference<PlayerScore> holder
                                                        = (AtomicReference<PlayerScore>) ctx.getAttribute("highScore");
                                                        while (true) {
                                                        HighScore old = holder.get();
                                                        if (old.score >= newScore.score)
                                                        break;
                                                        else if (holder.compareAndSet(old, newScore))
                                                        break;
                                                        }
                                                        }


                                                        Source: http://www.ibm.com/developerworks/library/j-jtp09238/index.html






                                                        share|improve this answer













                                                        Another simple example is to do a safe-thread modification in a session object.



                                                        public PlayerScore getHighScore() {
                                                        ServletContext ctx = getServletConfig().getServletContext();
                                                        AtomicReference<PlayerScore> holder
                                                        = (AtomicReference<PlayerScore>) ctx.getAttribute("highScore");
                                                        return holder.get();
                                                        }

                                                        public void updateHighScore(PlayerScore newScore) {
                                                        ServletContext ctx = getServletConfig().getServletContext();
                                                        AtomicReference<PlayerScore> holder
                                                        = (AtomicReference<PlayerScore>) ctx.getAttribute("highScore");
                                                        while (true) {
                                                        HighScore old = holder.get();
                                                        if (old.score >= newScore.score)
                                                        break;
                                                        else if (holder.compareAndSet(old, newScore))
                                                        break;
                                                        }
                                                        }


                                                        Source: http://www.ibm.com/developerworks/library/j-jtp09238/index.html







                                                        share|improve this answer












                                                        share|improve this answer



                                                        share|improve this answer










                                                        answered Jul 15 '15 at 13:02









                                                        DherikDherik

                                                        5,79744374




                                                        5,79744374






























                                                            draft saved

                                                            draft discarded




















































                                                            Thanks for contributing an answer to Stack Overflow!


                                                            • Please be sure to answer the question. Provide details and share your research!

                                                            But avoid



                                                            • Asking for help, clarification, or responding to other answers.

                                                            • Making statements based on opinion; back them up with references or personal experience.


                                                            To learn more, see our tips on writing great answers.




                                                            draft saved


                                                            draft discarded














                                                            StackExchange.ready(
                                                            function () {
                                                            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f3964211%2fwhen-to-use-atomicreference-in-java%23new-answer', 'question_page');
                                                            }
                                                            );

                                                            Post as a guest















                                                            Required, but never shown





















































                                                            Required, but never shown














                                                            Required, but never shown












                                                            Required, but never shown







                                                            Required, but never shown

































                                                            Required, but never shown














                                                            Required, but never shown












                                                            Required, but never shown







                                                            Required, but never shown







                                                            Popular posts from this blog

                                                            MongoDB - Not Authorized To Execute Command

                                                            How to fix TextFormField cause rebuild widget in Flutter

                                                            Npm cannot find a required file even through it is in the searched directory