单例模式

单例模式

1、懒汉式,线程不安全

 //只使用于单线程
 public class Singleton1 {
     private Singleton1() {
 
    }
 
     private static Singleton1 instance = null;
 
     public static Singleton1 getInstance() {
         if (instance == null) {
             instance = new Singleton1();
        }
         return instance;
    }
 }

2、懒汉式,线程安全

 public class Singleton1 {
     private Singleton1() {
 
    }
 
     private static Singleton1 instance = null;
 
     public static synchronized Singleton1 getInstance() {
         if (instance == null) {
             instance = new Singleton1();
        }
         return instance;
    }
 }
 
 public class Singleton2 {
     private Singleton2() {
 
    }
 
     private static volatile Object syncObj = new Object();
     private static Singleton2 instance = null;
 
     public static Singleton2 getInstance() {
         synchronized (syncObj) {
             if (instance == null) {
                 instance = new Singleton2();
            }
             return instance;
        }
    }
 }

3、双重校验锁

剑指offer:加锁耗费时间。加同步锁两次判断实例是否已存在。

 
 public class Singleton3 {
     
     private Singleton3() {
         
    }
 
     private static Singleton3 instance = null;
     private static Object synObj = new Object();
     public static Singleton3 getInstance() {
         if (instance == null) {
             synchronized (synObj) {
                 if (instance == null) {
                     instance = new Singleton3();
                }
            }
        }
         return instance;
    }
 }

4、饿汉式 static final field

这种方法非常简单,因为单例的实例被声明成 static 和 final 变量了,在第一次加载类到内存中时就会初始化,所以创建实例本身是线程安全的。

 //饿汉式
 public class Singleton4 {
     private Singleton4() {
    }
     //类加载时就初始化
     private static final Singleton4 instance = new Singleton4();
 
     public static Singleton4 getInstance() {
         return instance;
    }
 }
 

5、静态内部类 static nested class

 public class Singleton {  
     private static class SingletonHolder {  
         private static final Singleton INSTANCE = new Singleton();  
    }  
     private Singleton (){}  
     public static final Singleton getInstance() {  
         return SingletonHolder.INSTANCE;
    }  
 }

剑指offer:

 public class Singleton5 {
     private Singleton5() {
 
    }
 
     public static Singleton5 Instance() {
         return Nested.instance;
    }
 
     private static class Nested {
         Nested() {
 
        }
         static Singleton5 instance = new Singleton5();
    }
 }

6、枚举 Enum

用枚举写单例实在太简单了!这也是它最大的优点。下面这段代码就是声明枚举实例的通常做法。

 public enum EasySingleton{
    INSTANCE;
 }

我们可以通过EasySingleton.INSTANCE来访问实例,这比调用getInstance()方法简单多了。创建枚举默认就是线程安全的,所以不需要担心double checked locking,而且还能防止反序列化导致重新创建新的对象。

posted @ 2021-04-09 10:28  大D同学  阅读(53)  评论(0)    收藏  举报