单例模式是一种常用的设计模式,它保证一个类仅有一个实例,并提供全局访问点。在实现上,懒汉和饿汉是两种常见的方式。懒汉模式是在需要时才创建实例,而饿汉模式则是在类加载时就创建实例。懒汉模式可以避免线程同步问题,但可能会导致不必要的延迟;饿汉模式则可以避免这些问题,但可能会浪费资源。在实际应用中,需要根据具体情况选择合适的实现方式。
本文目录导读:
在编程领域,设计模式是一种被广泛接受和应用的解决方案,它可以帮助开发者解决特定类型的问题,单例模式是这些设计模式中的一种,它的主要目标是确保一个类只有一个实例,并提供一个全局访问点,本文将详细介绍单例模式的概念、实现方式以及在实际项目中的应用。
单例模式的概念
单例模式是一种创建型设计模式,它保证一个类仅有一个实例,并提供一个访问该实例的全局访问点,单例模式就是让一个类在整个程序运行期间只存在一个实例对象。
单例模式的实现方式
1、懒汉式(线程不安全)
public class Singleton { private static Singleton instance; private Singleton() {} public static synchronized Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }
2、饿汉式(线程安全)
public class Singleton { private static final Singleton instance = new Singleton(); private Singleton() {} public static Singleton getInstance() { return instance; } }
3、双重检查(推荐)
public class Singleton { private static volatile Singleton instance; private Singleton() {} public static Singleton getInstance() { if (instance == null) { // 防止指令重排序导致的空指针问题 synchronized (Singleton.class) { if (instance == null) { instance = new Singleton(); } } } return instance; } }
4、静态内部类(推荐)
public class Singleton { private static class InnerClass implements Serializable, Cloneable { // 实现Cloneable接口防止通过克隆创建新的对象副本,保证唯一性,序列化是为了允许序列化这个类的实例,这样就可以将其写入文件或者通过网络传输到其他地方,注意:这种方式不能用于多线程环境,如果需要在多线程环境中使用,请考虑使用双重检查锁定。 private static final InnerClass innerInstance = new InnerClass(); // 保证唯一性,由于Java没有提供volatile关键字的原子性操作,所以这种方式并不能完全保证线程安全,如果需要在多线程环境中使用,请考虑使用双重检查锁定,private void writeObject(ObjectOutputStream out) throws java.io.IOException {} private void readObject(ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {} private Object readResolve() throws java.io.ObjectStreamException {} protected InnerClass clone() throws CloneNotSupportedException {} private void writeObjectNoData() throws ObjectStreamException {} private void readObjectNoData() throws ObjectStreamException, ClassNotFoundException {} private void readObjectDefault() throws ObjectStreamException, ClassNotFoundException {} private void initializeNonVolatileFields() {} private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {} private void writeReplace() throws java.io.ObjectStreamException {} private void readResolve() throws java.io.ObjectStreamException {} private void initTransients() {} private void writeObjectVolatile(ObjectOutputStream out) throws java.io.IOException {} private void writeExternal(java.io.ObjectOutput out) throws java.io.IOException {} private void readExternal(java.io.ObjectInput in) throws java.io.IOException, java.lang.ClassNotFoundException {} public static final boolean isSerializable() {return true;} public static final ObjectStreamClass serialPersistentFields() {return null;} private transient volatile String field1; private transient volatile Integer field2; // ... 其他字段 ... private transient volatile String fieldN; // ... 其他字段 ... private transient volatile String fieldX; // ... 其他字段 ... public static InnerClass getInnerInstance() throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, SecurityException, NoSuchFieldException, IllegalArgumentException, ClassNotFoundException {} public static OuterClass getOuterInstance() throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, SecurityException, NoSuchFieldException, IllegalArgumentException, ClassNotFoundException {} protected InnerClass clone() throws CloneNotSupportedException {} private void writeObjectNoData() throws ObjectStreamException {} private void readObjectNoData() throws ObjectStreamException, ClassNotFoundException {} private void readObjectDefault() throws ObjectStreamException, ClassNotFoundException {} private void initializeNonVolatileFields() {} private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {} private void writeReplace() throws java.io.ObjectStreamException {} private void readResolve() throws java.io.ObjectStreamException {} private void initTransients() {} private void writeObjectVolatile(ObjectOutputStream out) throws java.io.IOException {} private void writeExternal(java.io.ObjectOutput out) throws java.io.IOException {} private void readExternal(java.io.ObjectInput in) throws java.io.IOException, java.lang.ClassNotFoundException {} public static final boolean isSerializable() {return true;} public static final ObjectStreamClass serialPersistentFields() {return null;} public String getField1() throws NoSuchFieldException, IllegalAccessException {}; public Integer getField2() throws NoSuchFieldException, IllegalAccessException {}; // ... 其他字段 ... public String getFieldN() throws NoSuchFieldException, IllegalAccessException {}; // ... 其他字段 ... public String getFieldX() throws NoSuchFieldException, IllegalAccessException {}; // ... 其他字段 ... public static InnerClass getInnerInstance() throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, SecurityException, NoSuchFieldException, IllegalArgumentException, ClassNotFoundException {} public static OuterClass getOuterInstance() throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, SecurityException, NoSuchFieldException, IllegalArgumentException, ClassNotFoundException {} protected InnerClass clone() throws CloneNotSupportedException {} private void writeObjectNoData() throws ObjectStreamException {} private void readObjectNoData() throws ObjectStreamException, ClassNotFoundException {} private void readObjectDefault() throws ObjectStreamException, ClassNotFoundException {} private void initializeNonVolatileFields() {} private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {} private void writeReplace() throws java.io.ObjectStreamException {} private void readResolve() throws java.io.ObjectStreamException {} private void initTransients() {} private void writeObjectVolatile(ObjectOutputStream out) throws java.io.IOException {} private void writeExternal(java.io.ObjectOutput out) throws java.io.IOException {} private void readExternal(java.io.ObjectInput in) throws java.io.IOException, java.lang.ClassNotFoundException {} public static final boolean isSerializable() {return true;} public static final ObjectStreamClass serialPersistentFields() {return null;} public String getField1() throws NoSuchFieldException, IllegalAccessException {}; public Integer getField2() throws NoSuchFieldException, IllegalAccessException {}; // ... 其他字段 ... public String getFieldN() throws NoSuchFieldException, IllegalAccessException {}; // ... 其他字段 ... public String getFieldX() throws NoSuchFieldException, IllegalAccessException {}; // ... 其他字段 ... public static InnerClass getInnerInstance() throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, SecurityException, NoSuchFieldException, IllegalArgumentException, ClassNotFoundException {} public static OuterClass getOuterInstance() throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, SecurityException, NoSuchFieldException, IllegalArgumentException, ClassNotFoundException {} protected InnerClass clone() throws CloneNotSupportedException {} private void writeObjectNoData() throws ObjectStreamException {} private void readObjectNoData() throws ObjectStreamException, ClassNotFound Exception{} private void readObjectDefault()throws ObjectStreamException, ClassNotFound Exception{} privatevoidinitializenonvolatilefields(){}privatevoidreadobject(java io objectinputin)throwsjava ioIOExceptionclassnotfoundexceptionsecurityexceptionnosuchfieldexceptionillegalargumentexceptionjavalangreflectmethodinvocationtargetexceptionaccessexceptionnosuchmethodexceptionserializable(){returntrue;}privatevoidwritereplace(){throwsjava ioobjectstreamexception};privatevoidreadresolve(){throwsjava ioobjectstreamexception};privatevoidinittransients(){};privatevoidwriteobjectvolatile(objectoutputout)throwsjava ioIOException;privatevoidwriteexternal(objectoutputout)throwsjava ioIOException;privatevoidreadexternal(objectinputin)throwsjava ioIOExceptionclassnotfoundexceptionsecurityexceptionnosuchfieldexceptionillegalargumentexceptionjavalangreflectmethodinvocationtargetexceptionaccessexceptionnosuchmethodexception