PS:这是一个小白的学习记录之路。大神看见不要笑,狮虎看见不要生气的哈。
题目:单例模式的实现方式
解决思路:狮虎说不知道就要问度娘(PS:狮虎,不要打了,疼···我真的不知道单例)
解决步骤:狮虎说不知道就要多学习(PS:我认真的抄了一遍,狮虎,我真的很认真的抄了~)
答案:maybe~可能大概,狮虎·····别·····打·····我
首先,对于不懂什么是单例的我来说,java的单例模式是一种常见的设计模式。
单例模式定义:确保某个类只有一个实例,而且自行能够实例化并向整个系统提供这个实例。
可以被设计单例模式的对象:线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序等或多或少具有资源管理器的功能的对象
单例的特点:
单例类只有一个实例;单例类必须自己创建自己的唯一实例;单例类必须给所有其他对象提供这一实例;
单例的模式:饿汉模式;懒汉模式;双重检查模式;静态内部类单例模式;使用容器实现单例模式
1:饿汉模式:
代码如下:
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton(){
}
public static Singleton getInstance(){
return instance;
}
}
PS:此种单例方法,在加载类的时候已完成实例化,因此会加载类的时间比较慢,调用此类调用类方法需要的时间较短,可避免多线程同步问题。
2:懒汉模式(线程不安全)
public class Singleton {
private static Singleton instance;
private Singleton (){
}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
PS:此方法实现了懒调用,节约了资源,但用户第一次调用的时候需要实例化,反应稍慢。在多线程无法正常使用。
3:懒汉模式(安全)
public class Singleton {
private static Singleton instance;
private Singleton (){
}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
PS:这种方法虽然实现了在多线程可以使用,但是每次调用getInstance方法时都需要进行同步,造成不必要的同步开销,而且大部分时候我们是用不到同步的,所以不建议用这种模式。
4. 双重检查模式 (DCL)
public class Singleton {
private volatile static Singleton instance = new Singleton();
private Singleton(){}
public static Singleton getInstance(){
if(instance==null){
synchronized (Singleton.class){
if(instance==null){
instance=new Singleton();
}
}
}
return instance;
}
}
PS:此方法在getSingleton方法中对singleton进行了两次判空,第一次是为了不必要的同步,第二次是在singleton等于null的情况下才创建实例。DCL优点是资源利用率高,第一次执行getInstance时单例对象才被实例化,效率高。缺点是第一次加载时反应稍慢一些,在高并发环境下也有一定的缺陷,虽然发生的概率很小。DCL虽然在一定程度解决了资源的消耗和多余的同步,线程安全等问题,但是他还是在某些情况会出现失效的问题,也就是DCL失效。
5. 静态内部类单例模式
public class Singleton {
private Singleton(){
}
public static Singleton getInstance(){
return SingletonHolder.sInstance;
}
private static class SingletonHolder{
private static final Singleton sInstance=new Singleton();
}
}
PS:第一次加载Singleton类时并不会初始化sInstance,只有第一次调用getInstance方法时虚拟机加载SingletonHolder 并初始化sInstance ,这样不仅能确保线程安全也能保证Singleton类的唯一性,推荐使用此种单例模式。
6. 枚举单例
public enum Singleton {
INSTANCE;
public void doSomeThing() {
}
}
PS:默认枚举实例的创建是线程安全的,并且在任何情况下都是单例
PS:杜绝单例对象被反序列化是重新生成对象代码
private Object readResolve() throws ObjectStreamException{
return singleton;
}
7:使用容器实现单例模式
public class SingletonManager{private static MapobjMap=new HashMap();
private Singleton(){
}
private static void registerService( String key, Object instance){
if(!objMap.containsKey(key)){
objMap.put(key, instance) ;
}
}
public static Object getService(String key){
return objMap.get(key);
}
}
PS:用SingletonManager 将多种的单例类统一管理,在使用时根据key获取对象对应类型的对象。这种方式使得我们可以管理多种类型的单例,并且在使用时可以通过统一的接口进行获取操作,降低了用户的使用成本,也对用户隐藏了具体实现,降低了耦合度。
PS:好多好多,笔记先记在这里,后面续继续理解记忆。