Java Single Case Mode for Multithreaded Actual Warfare and Detailed Instance for Multithreaded

  • 2021-06-29 10:54:10
  • OfStack

1. Load Now/Hungry Han Mode


//  Load Now / Hungry Han Mode 
public class MyObject {
 private static final MyObject myObject = new MyObject();
 private MyObject() {
 }
 public static MyObject getInstance() {
 return myObject;
 }
}

Immediate Load/Hungry Man mode creates a static object for the system to use at the same time the class is created, without thread security issues

2. Delayed Loading/Lazy Mode


//  Delayed Loading / Lazy Man Mode 
public class MyObject {
 private static MyObject myObject;
 private MyObject() {
 }
 public static MyObject getInstance() {
 if (myObject == null) {
  myObject = new MyObject();
 }
 return myObject;
 }
}

Delayed load/lazy mode is when an instance is created when a method is invoked. In a multithreaded environment, multiple instances are taken out, which is contrary to the original intention of the singleton mode.

1) Delayed load/lazy mode creates multiple instances in a multithreaded environment:


//  Delayed Loading / Lazy Man Mode 
public class MyObject {
 private static MyObject myObject;
 private MyObject() {
 }
 public static MyObject getInstance() {
 try {
  if (myObject == null) {
  TimeUnit.SECONDS.sleep(3);
  myObject = new MyObject();
  }
 } catch (InterruptedException e) {
  e.printStackTrace();
 }
 return myObject;
 }
}

public class MyThread extends Thread {
 @Override
 public void run() {
 System.out.println(MyObject.getInstance().hashCode());
 }
}

public class Run {
 public static void main(String[] args) {
 MyThread myThread = new MyThread();
 MyThread myThread2 = new MyThread();
 MyThread myThread3 = new MyThread();
 myThread.start();
 myThread2.start();
 myThread3.start();
 }
}

Run result: hashCode printed 3 times is not exactly equal

2) Solve thread security issues by declaring the synchronized keyword:


//  Delayed Loading / Lazy Man Mode 
public class MyObject {
 private static MyObject myObject;
 private MyObject() {
 }
 public static synchronized MyObject getInstance() {
 try {
  if (myObject == null) {
  TimeUnit.SECONDS.sleep(3);
  myObject = new MyObject();
  }
 } catch (InterruptedException e) {
  e.printStackTrace();
 }
 return myObject;
 }
}

With the synchronized keyword, this method is inefficient and runs synchronously. If the next thread wants to get the object, it must wait until one thread releases the lock before it can continue executing

3) Use synchronous code blocks to solve thread security issues:


//  Delayed Loading / Lazy Man Mode 
public class MyObject {
 private static MyObject myObject;
 private MyObject() {
 }
 public static MyObject getInstance() {
 try {
  //  Amount to public static synchronized MyObject getInstance()
  synchronized (MyObject.class) {
  if (myObject == null) {
   TimeUnit.SECONDS.sleep(3);
   myObject = new MyObject();
  }
  }
 } catch (InterruptedException e) {
  e.printStackTrace();
 }
 return myObject;
 }
}

Join the Synchronization Code Block, which is also very inefficient and runs synchronously as the synchronized Synchronization Method 1

4) Separate synchronization for some important code


//  Delayed Loading / Lazy Man Mode 
public class MyObject {
 private static MyObject myObject;
 private MyObject() {
 }
 public static MyObject getInstance() {
 try {
  if (myObject == null) {
  TimeUnit.SECONDS.sleep(3);
  synchronized (MyObject.class) {
   myObject = new MyObject();
  }
  }
 } catch (InterruptedException e) {
  e.printStackTrace();
 }
 return myObject;
 }
}

This method only synchronizes the key code of the instantiated object, which really improves the efficiency of the statement structure.However, if it is multi-threaded, the result of getting the same instance object cannot be resolved

5) Use DCL double check lock mechanism


//  Delayed Loading / Lazy Man Mode 
public class MyObject {
 private volatile static MyObject myObject;
 private MyObject() {
 }
 public static MyObject getInstance() {
 try {
  if (myObject == null) {
  TimeUnit.SECONDS.sleep(3);
  synchronized (MyObject.class) {
   if (myObject == null) {
   myObject = new MyObject();
   }
  }
  }
 } catch (InterruptedException e) {
  e.printStackTrace();
 }
 return myObject;
 }
}

Using DCL double check lock mechanism ensures both asynchronous execution without synchronous code and the effect of a singleton

3. Use static internal classes to implement singleton mode


public class MyObject {
 private static class MyObjectHandler {
 private static MyObject myObject = new MyObject();
 }
 private MyObject() {
 }
 public static MyObject getInstance() {
 return MyObjectHandler.myObject;
 }
}

4. Use static code blocks to implement singleton mode


//  Delayed Loading / Lazy Man Mode 
public class MyObject {
 private static MyObject myObject;
 private MyObject() {
 }
 public static MyObject getInstance() {
 if (myObject == null) {
  myObject = new MyObject();
 }
 return myObject;
 }
}
0

5. Use enum enumeration to implement singleton mode


//  Delayed Loading / Lazy Man Mode 
public class MyObject {
 private static MyObject myObject;
 private MyObject() {
 }
 public static MyObject getInstance() {
 if (myObject == null) {
  myObject = new MyObject();
 }
 return myObject;
 }
}
1

Enumeration enum is similar to static code blocks in that when using enumeration classes, construction methods are automatically invoked to implement the singleton design pattern

summary


Related articles: