23 design patterns – singleton patterns

1. Some notes on the singleton pattern

Singleton pattern: Ensures that a class has at most one instance, providing a global access point

Note:

  • A singleton class can have only one instance

  • A singleton class must create its own unique instance

  • The singleton class must provide this instance to all other objects

Singleton patterns can be divided into two types: preloading and lazy loading (i.e., hungriness and slacker)

2. Detailed explanation of the two forms

1. Preloading (hungry)

Preloading. The singleton is not used yet, but is already loaded into memory.

If the singleton is not used, the object is loaded into memory, which wastes memory.

2. Lazy loading (lazy style)

To avoid the waste of memory, you can use lazy loading, that is, the singleton object is created at the time.

3. Singleton pattern and thread safety

  • The hant has only one return instance statement to ensure thread-safety. But will cause memory waste;

  • Lazy doesn’t waste memory, but it doesn’t keep threads safe. First, the if judgment and its in-memory execution code are nonatomic. Second, new Singleton() does not guarantee sequential execution. Threads are not safe if they are not atomic or sequential.

  • Why new Singleton() cannot guarantee orderliness. Creating an object consists of three steps:

The JVM reorders code that has no dependencies to improve program performance, and the above 2 and 3 lines may be reordered. We use two threads to show that threads are not safe. Both threads A and B create objects. Where, the reordering of A2 and A3 causes thread B to determine at B1 that instance is not null, and thread B will next access the object referenced by instance. At this point, thread B will access an uninitialized object (thread unsafe).

4. Lazy thread-safe solutions

Use the synchronized keyword. Synchronized does ensure thread safety by loading the getInstace() function.

Synchronized is the most commonly used keyword in Java multithreaded programming. All Java objects have their own unique implicit synchronization lock. The lock can only be acquired by one thread at a time, and any other thread that attempts to acquire the lock is blocked in the object’s waiting queue until the thread that acquired the lock releases the lock.

Note: Calling the getInstance() method frequently wakes up and blocks the thread with or without an initialized instance. To avoid time-consuming context switching by threads, there is no need to use synchronized locking if the object is already instantiated.

Add sychronized to the if(instance==null) statement to ensure that instance is not instantiated.

New object code is not sequential. The keyword volatile is used to ensure sequential object instantiation.

That is to ensure lazy thread safety.

Java geek mind

Scan wechat and follow the official account