一、定义及应用

  单例模式,是一种常用的软件设计模式,在使用这个设计模式时,单例对象的类要保证只有一个实例存在。

  许多时候整个系统只需要有一个全局对象,这样有利于我们协调整个系统的行为。比如服务器程序中,服务器程序的配置信息存储在一个文件中,使用一个单例对象同意读取,服务进程中的其他对象再通过这个单例对象获取这些配置信息。这种方式简化了复杂环境下的配置管理。同样,线程池、连接池也是通过单例模式进行管理。

二、实现

1)、两懒汉方式

public class Singleton{//非线程安全
  private static Singleton instance;
  private Singleton(){};
  public static Singleton getInstance(){
     if(instance==null){
         instance=new singleton();
   }
     return instance;
  }  
}

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 class SingletonHolder{
    private static final Singlton instance=new Singleton();
  }
  private Singleton(){};
  public static Singleton getInstance(){
    return SingletonHolder.instance;
  }
}

4)、枚举

public enum Singleton{
  INSTANCE;
  //....other function    
}

  写枚举单例的方式,它可能包含实例变量和实例方法,但是简单来说我什么都没用,需要注意的是如果你使用实例方法,你就需要确保方法的线程安全性,避免它会影响对象的状态。通常情况下枚举里面创建实例是线程安全的,但是其它的方法就需要编程者自己去考虑了。

5)、双校验

public class Singleton{
  private volatile static Singleton instance;//volatile关键字保证当instance变量被初始
  private Singleton(){};//化Singleton实例后,多个线程正确的处理instance变量
  public static Singleton getInstance(){
    if(instance==null){
      synchronize(Singleton.class){
        if(instance == null){
          instance = new Singleton();
        }
      }
    }
    return instance;
  }
}

三、防止破坏单例模式

1、阻止clone()方法创建单例实例的另一个实例

  1)override clone()方法

    protected Object clone() throws CloneNotSupportedException{
        throw new CloneNotSupportedException();
    }

  2)一个是单例类一定要是final的,这样用户就不能继承它了

如果有其他方法可以交流交流!

2、防止反射破坏

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class Singletom {

    private static final Singletom instance=new Singletom();
    private Singletom(){};
    public static Singletom getInstance(){
        return instance;
    }
    
    public static void main(String [] args) throws SecurityException, NoSuchMethodException, IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException{
        Class<Singletom> clazz = Singletom.class;
        Constructor<Singletom> constructor = clazz.getDeclaredConstructor();
        
        constructor.setAccessible(true);
        System.out.println(Singletom.instance == constructor.newInstance());
    }
}
View Code

相关文章:

猜你喜欢
  • 2021-12-03
  • 2021-12-02
  • 2021-12-23
  • 2021-12-19
  • 2018-11-02
相关资源
相似解决方案