Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Case Analysis of Singleton pattern in Java

2025-01-17 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

This article introduces the relevant knowledge of "singleton pattern instance Analysis in Java". Many people will encounter this dilemma in the operation of actual cases, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!

1. Definition

The singleton pattern (Singleton Pattern) is to ensure that there is absolutely only one instance of a class in any case and provides a global access point.

Hides all of its constructors.

Belongs to the creative mode.

2. Applicable scenarios

Make sure there is absolutely only one instance in any case.

3. Common writing methods

The first: hungry Chinese singleton: create an instance when the singleton class is loaded for the first time

/ * * @ Package: com.hzg.study.design.pattern.singleton.hungry * @ Description: single case of hungry Han style * @ Author: HuangZhiGao * @ CreateDate: 2022-02-18 16:15 * / public class HungrySingleton {private static final HungrySingleton INSTANCE = new HungrySingleton () / * privatization constructor * / private HungrySingleton () {} / * global access point * / public static HungrySingleton getInstance () {return INSTANCE;}}

How to write a single example of static code block in hungry Han style:

/ * * @ Package: com.hzg.study.design.pattern.singleton.hungry * @ Description: hungry Han singleton (static code block initialization) * @ Author: HuangZhiGao * @ CreateDate: 2022-02-18 16:15 * / public class HungryStaticSingleton {private static final HungryStaticSingleton INSTANCE; / * static code block * / static {INSTANCE = new HungryStaticSingleton () } / * privatization constructor * / private HungryStaticSingleton () {} / * Global access point * / public static HungryStaticSingleton getInstance () {return INSTANCE;}}

Second: lazy singleton: the instance is created only when it is called by an external class.

/ * * @ Package: com.hzg.study.design.pattern.singleton.lazy * @ Description: lazy singles * @ Author: HuangZhiGao * @ CreateDate: 2022-02-18 16:24 * / public class LazySingleton {private static LazySingleton INSTANCE = null / * privatization constructor * / private LazySingleton () {} / * global access point * / public static LazySingleton getInstance () {if (INSTANCE = = null) {INSTANCE = new LazySingleton ();} return INSTANCE;}}

Lazy singleton static anonymous inner class writing (best performance):

/ * @ Package: com.hzg.study.design.pattern.singleton.lazy * @ Description: lazy singleton (anonymous static inner class) (best performance) * @ Author: HuangZhiGao * @ CreateDate: 2022-02-18 18:00 * / public class LazyInnerClazzSingleton implements Serializable {/ * privatization constructor * / private LazyInnerClazzSingleton () {} / * * global Access point * / public static final LazyInnerClazzSingleton getInstance () {return LazyHolder.INSTANCE } private static class LazyHolder {private static final LazyInnerClazzSingleton INSTANCE = new LazyInnerClazzSingleton ();}}

The third: registration singleton: each instance is cached in a unified container and the instance is obtained using a unique ID.

Registration-style singleton enumeration:

/ * * @ Package: com.hzg.study.design.pattern.singleton.registry * @ Description: registered singleton-enumerated singleton * @ Author: HuangZhiGao * @ CreateDate: 2022-02-21 10:24 * / public enum EnumSingleton {INSTANCE / * if you need to make other objects singletons, simply change data to the target class object * * through getter and setter operations * / private Object data; public Object getData () {return data;} public void setData (Object data) {this.data = data;} public static EnumSingleton getInstance () {return INSTANCE;}}

Common registration singleton writing in Spring:

/ * @ Package: com.hzg.study.design.pattern.singleton.registry * @ Description: common registration singleton writing in Spring * @ Author: HuangZhiGao * @ CreateDate: 2022-02-21 10:54 * / public class ContainerSingleton {/ * * spring ioc * / private static Map container = new ConcurrentHashMap () Private ContainerSingleton () {} public static Object getBean (String clazzName) {/ / add synchronized code block to ensure thread safety synchronized (container) {if (! container.containsKey (clazzName)) {Object object = null; try {object = Class.forName (clazzName). NewInstance () Container.put (clazzName, object);} catch (Exception e) {e.printStackTrace ();} return object;} return container.get (clazzName);}

The fourth kind: ThreadLocal thread singleton: ensures the global uniqueness within the thread and is inherently thread safe.

/ * @ Package: com.hzg.study.design.pattern.singleton.threadlocal * @ Description: ThreadLocal thread singleton (pseudo-safe) * @ Description: you can use ThreadLocal to dynamically switch data sources * @ Author: HuangZhiGao * @ CreateDate: 2022-02-21 11:10 * / public class ThreadLocalSingleton {public static final ThreadLocal THREAD_LOCAL = new ThreadLocal () {@ Override protected ThreadLocalSingleton initialValue () {return new ThreadLocalSingleton () }}; private ThreadLocalSingleton () {} public static ThreadLocalSingleton getInstance () {return THREAD_LOCAL.get ();}} 4, how to prevent a single case from being destroyed. Single case of multithread failure and its solution

Take the lazy single case LazySingleton as an example:

First, write a thread implementation class, as follows:

Import com.hzg.study.design.pattern.singleton.lazy.LazySingleton;/** * @ Package: com.hzg.study.design.pattern.singleton.lazy.test * @ Description: * @ Author: HuangZhiGao * @ CreateDate: 2022-02-18 16:32 * / public class ExecutorThread implements Runnable {@ Override public void run () {LazySingleton instance = LazySingleton.getInstance (); System.out.println (Thread.currentThread (). GetName () + ":" + instance);}}

Main method test:

Public class LazySingletonTest {public static void main (String [] args) {Thread thread1 = new Thread (new ExecutorThread ()); thread1.start (); Thread thread2 = new Thread (new ExecutorThread ()); thread2.start (); System.out.println ("- -");}}

Test results: it is clear that there are two different examples

Solution 1: add synchronized keyword to modify getInstance method

Public class LazySingleton {private static LazySingleton INSTANCE = null; / * privatization constructor * / private LazySingleton () {} / * Global access Point * * synchronized keyword modifier * / public static synchronized LazySingleton getInstance () {if (INSTANCE = = null) {INSTANCE = new LazySingleton ();} return INSTANCE }}

Solution 2: double check lock DoubleCheck

/ * * @ Package: com.hzg.study.design.pattern.singleton.lazy * @ Description: lazy singleton (double-checked lock) * @ Author: HuangZhiGao * @ CreateDate: 2022-02-18 17:08 * / public class LazyDoubleCheckSingleton {/ * volatile keyword modification to avoid problems caused by instruction reordering * / private volatile static LazyDoubleCheckSingleton INSTANCE = null / * privatization constructor * / private LazyDoubleCheckSingleton () {} / * * Global access point * * double check lock * / public static LazyDoubleCheckSingleton getInstance () {if (INSTANCE = = null) {synchronized (LazyDoubleCheckSingleton.class) {if (INSTANCE = = null) { INSTANCE = new LazyDoubleCheckSingleton () } return INSTANCE;}} 2. Single case of reflection failure and its solution

Take LazyInnerClazzSingleton as an example to write a single static anonymous inner class of lazy Chinese style:

Main method test:

Public class LazyInnerClazzSingletonTest {public static void main (String [] args) {try {Class aClazz = LazyInnerClazzSingleton.class; Constructor declaredConstructor = aClazz.getDeclaredConstructor (null); declaredConstructor.setAccessible (true); LazyInnerClazzSingleton instance1 = declaredConstructor.newInstance (); LazyInnerClazzSingleton instance2 = LazyInnerClazzSingleton.getInstance (); System.out.println (instance1); System.out.println (instance2) System.out.println (instance1 = = instance2);} catch (Exception e) {e.printStackTrace ();}

Test results: two different examples are built

Solution: add the following if judgment to the constructor

Public class LazyInnerClazzSingleton implements Serializable {/ * privatization constructor * / private LazyInnerClazzSingleton () {if (null! = LazyHolder.INSTANCE) {throw new RuntimeException ("multiple instances are not allowed to be built");}} / * global access point * / public static final LazyInnerClazzSingleton getInstance () {return LazyHolder.INSTANCE } private static class LazyHolder {private static final LazyInnerClazzSingleton INSTANCE = new LazyInnerClazzSingleton ();}}

Test again:

3. Serialization damage singleton and its solution

Take lazy singleton static anonymous inner class writing LazyInnerClazzSingleton as an example: note that the serialization interface Serializable must be implemented first.

Main method test:

Public static void main (String [] args) {LazyInnerClazzSingleton instance1 = LazyInnerClazzSingleton.getInstance (); LazyInnerClazzSingleton instance2 = null; try (FileOutputStream fileOutputStream = new FileOutputStream ("LazyInnerClazzSingleton.obj"); ObjectOutputStream objectOutputStream = new ObjectOutputStream (fileOutputStream); FileInputStream fileInputStream = new FileInputStream ("LazyInnerClazzSingleton.obj"); ObjectInputStream objectInputStream = new ObjectInputStream (fileInputStream) ) {/ / serialize objectOutputStream.writeObject (instance1); objectOutputStream.flush (); / / deserialize instance2 = (LazyInnerClazzSingleton) objectInputStream.readObject (); System.out.println (instance1); System.out.println (instance2); System.out.println (instance1 = = instance2) } catch (Exception e) {e.printStackTrace ();}}

Test results: two different examples are built

Solution: add readResolve method

Public class LazyInnerClazzSingleton implements Serializable {/ * privatization constructor * / private LazyInnerClazzSingleton () {if (null! = LazyHolder.INSTANCE) {throw new RuntimeException ("multiple instances are not allowed to be built");}} / * global access point * / public static final LazyInnerClazzSingleton getInstance () {return LazyHolder.INSTANCE } private static class LazyHolder {private static final LazyInnerClazzSingleton INSTANCE = new LazyInnerClazzSingleton ();} / * the readResolve method is actually created twice, but the deserialized object is overwritten, and the previously deserialized object will be reclaimed by GC * occurs at the JVM level, which is relatively safe * / private Object readResolve () {return LazyHolder.INSTANCE 5. Advantages and disadvantages

Advantages:

There is only one instance in memory, which reduces memory overhead.

Multiple occupancy of resources can be avoided.

Set the global access point and strictly control the access.

Disadvantages:

There is no interface, so it is difficult to expand.

If you want to extend the singleton object, you can only modify the code and there is no other way.

Does not conform to the principle of opening and closing

This is the end of "Singleton pattern instance Analysis in Java". Thank you for reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report