Java thread safe for you

Q

How should we guarantee thread safety in Java?

Conclusion

Storm

Java language specification

Especially in Java, the following control syntax is related to the elements that have appeared so far.

Practice

Consider the case where foo () and bar () are called from different threads multiple times at irregular intervals for the following implementation.

   public void foo() {
       _object.update();  // _Processing that changes the internal state of object
   }
   
   public void bar() {
       if (_object.enabled()) {
           _object.getData();  // enabled()Exception occurs when called when is false
       }
   }

No synchronized block

Since there is no guarantee of atomicity in the processing of bar (), the methods may be called in the following order. _object.enabled() -> _object.update() -> _object.getData()

   public void foo() {
       _object.update();
   }
   
   public void bar() {
       if (_object.enabled()) {
           _object.getData();  // _The internal state of object is not guaranteed
       }
   }

There is a synchronized block

A guarantee of synchronization is added during the processing within the block, that is, the atomicity is also guaranteed. 【 _object.update() 】 -> 【 _object.enabled() -> _object.getData() 】 -> 【 _object.update() 】

It is easy to understand if you have an image that is stored in the processing queue in block units.

   public void foo() {
       synchronized (this) {
           _object.update();
       }
   }
   
   public void bar() {
       synchronized (this) {
           if (_object.enabled()) {
               _object.getData();  // _The internal state of object is guaranteed
           }
       }
   }

There is only a part of synchronized block

Synchronize operations between blocks that specify the same object as an argument

The synchronized block is just a guarantee of synchronization as described above. The following implementation does not guarantee synchronization for the processing inside bar ().

   public void foo() {
       _object.update();
   }
   
   public void bar() {
       synchronized (this) {
           if (_object.enabled()) {
               _object.getData();  // _The internal state of object is not guaranteed
           }
       }
   }

Synchronized block for another object

A supplement just in case. Synchronization is not guaranteed for operations between blocks that specify different objects as arguments.

   public void foo() {
       synchronized (_SOME_OBJECT) {
           _object.update();
       }
   }
   
   public void bar() {
       synchronized (this) {
           if (_object.enabled()) {
               _object.getData();  // _The internal state of object is not guaranteed
           }
       }
   }

Digression

About lock objects

Deadlock resistance

In order to minimize the occurrence of deadlock, it is desirable to apply the following principles to the implementation.

Lock object selection

Also, in either case the lock object must not be null. This is guaranteed by adding the final modifier.

  //Recommended implementation

  class Shared {
      private final Object _LOCK_OBJECT = new Object();  //Don't make it static

      public void foo() {
          synchronized (_LOCK_OBJECT) {
              // do something
          }
      }

      public void bar() {
          synchronized (_LOCK_OBJECT) {
              // do something
          }
      }
  }

  class User {
      public void sample() {
          final Shared object = new Shared();
          new Thread(() -> object.foo()).start();
          new Thread(() -> object.bar()).start();
      }
  }
  //Implementations that use this for lock objects
  
  class Shared {
      public void foo() {
          synchronized (this) {
              // do something
          }
      }
      public void bar() {
          synchronized (this) {
              // do something
          }
      }
  }

  class User {
      public void sample() {
          final Shared object = new Shared();
          //This object instance serves as a reference to the shared internal implementation's lock object.
          //Therefore, it violates the principle of "minimizing the shared range of lock objects".
      }
  }

Lock object definition

Similarly, according to the principle of minimizing the sharing range, a lock object should be defined for each target for which thread safety is to be guaranteed.

  class Shared {
      //Lock target
      private final Data _dataA = new Data();
      private final Data _dataB = new Data();
      private final Data _dateC = new Data();
      private final Validator = _validator = new Validator();

      //Lock object
      private final Object _DATA_A_LOCK = new Object();
      private final Object _DATA_B_LOCK = new Object();
      private final Object _DATA_C_LOCK = new Object();

      public void foo() {
          synchronized (_DATA_A_LOCK) {
              _dataA.update();
          }
          synchronized (_DATA_B_LOCK) {
              _dataB.update();
          }
          synchronized (_DATA_C_LOCK) {
              _validator.execute();
              _dataC.update();
          }
      }

      public void bar() {
          synchronized (_DATA_A_LOCK) {
              _dataA.get();
          }
          synchronized (_DATA_B_LOCK) {
              _dataB.get();
          }
          synchronized (_DATA_C_LOCK) {
              _validator.execute();
              _dataC.get();
          }
      }
  }

one thing

Recommended Posts

Java thread safe for you
Thread safe summary ~ Java ~
thread safe process in java language
What is thread safe (with Java)
Java local variables are thread safe
Java thread processing
2017 IDE for Java
Java for statement
[Java] for statement, while statement
[Java] Package for management
[Java] for statement / extended for statement
Countermeasures for Java OutOfMemoryError
NLP for Java (NLP4J) (2)
(Memo) Java for statement
NLP for Java (NLP4J) (1)
Java Programming Thread Runnable
DateFormat is not thread safe
[Java] New Thread generation method (2)
Java update for Scala users
[Java] Basic statement for beginners
Books used for learning Java
2018 Java Proficiency Test for Newcomers-Basics-
[Java] Summary of for statements
Java for beginners, data hiding
[Java] Tips for writing source
Java installation location for mac
Java thread to understand loosely
Java application for beginners: stream
Java while and for statements
Weak reference of JAVA reused instance allocated for each thread
[Java] New Thread generation method (1)
C # cheat sheet for Java engineers
New grammar for Java 12 Switch statements
[Java] Can you explain this phenomenon?
[For beginners] Summary of java constructor
AWS SDK for Java 1.11.x and 2.x
Rock-paper-scissors game for beginners in Java
Java for beginners, expressions and operators 1
[Java] Memo for naming class names
[For beginners] Run Selenium in Java
Hello World for ImageJ Java Plugin
[OpenCV3.2.0] Eclipse (Java) settings (for Mac)
Java for beginners, expressions and operators 2
Enable OpenCV with java8. (For myself)
Spring Framework tools for Java developer
Can you do it? Java EE
java (use class type for field)
Build Java development environment (for Mac)
[Java & SpringBoot] Environment Construction for Mac
Notes on Android (java) thread processing
Settings for SSL debugging in Java
Generics of Kotlin for Java developers
Diary for Java SE 8 Silver qualification
[For Java beginners] About exception handling
Classes and instances Java for beginners
Modern best practices for Java testing
Do you use Stream in Java?
[Java] Where did you try using java?