单例模式

一 懒汉模式

 1 public class Singleton{
 2     private static Singleton singleton;
 3 
 4     private Singleton() {
 5     }
 6 
 7     public synchronized static Single newInstance() {
 8         if (singleton== null) {
 9             singleton= new Singleton();
10         }
11         return singleton;
12     }
13 }

 

  懒汉模式在类加载的时候就实例化对象,这种模式缺点是不用这个对象的时候也会消耗内存,优点是线程安全。

二 饿汉模式

 1 public class Singleton{  
 2     private static Singleton instance = null;  
 3     private Singleton(){}  
 4     public static Singleton newInstance(){  
 5         if(null == instance){  
 6             instance = new Singleton();  
 7         }  
 8         return instance;  
 9     }  
10 } 

  饿汉模式在我们需要用这个对象再去实例化对象,缺点是线程不安全,有可能实例化了两个对象,优点是不实例化的时候不消耗内存。

  以上两种单例都不是完美的单例,如果饿汉模式能线程安全就更完美了,线程安全自然想到加锁,但锁加的不好会非常消耗性能,如以下加锁方式就非常消耗性能:

 1 public class Singleton{  
 2     private static Singleton instance = null;  
 3     private Singleton(){}  
 4     public static synchronized Singleton newInstance(){  
 5         if(null == instance){  
 6             instance = new Singleton();  
 7         }  
 8         return instance;  
 9     }  
10 } 

  上面的代码虽然实现了线程安全,但是每次拿对象的时候都要排队,用的人多的时候就非常消耗性能了。

三 双重检查加锁

  这个方式还是基于饿汉模式,如果我们能在创建对象的时候加锁,那么就完美的解决了性能的问题,并且线程也安全了。

 

 1     public class Singleton {  
 2         private static Singleton instance = null;  
 3         private Singleton(){}  
 4         public static Singleton getInstance() {  
 5             if (instance == null) {  
 6                 synchronized (Singleton.class) {  
 7                     if (instance == null) {  
 8                         instance = new Singleton();  
 9                     }  
10                 }  
11             }  
12             return instance;  
13         }  
14     }  

静态内部类

1 public class Singleton{  
2     private static class SingletonHolder{  
3         public static Singleton instance = new Singleton();  
4     }  
5     private Singleton(){}  
6     public static Singleton newInstance(){  
7         return SingletonHolder.instance;  
8     }  
9 }

  这种方式同样利用了类加载机制来保证只创建一个instance实例。它与饿汉模式一样,也是利用了类加载机制,因此不存在多线程并发的问题。不一样的是,它是在内部类里面去创建对象实例。这样的话,只要应用中不使用内部类,JVM就不会去加载这个单例类,也就不会创建单例对象,从而实现懒汉式的延迟加载。也就是说这种方式可以同时保证延迟加载和线程安全。

 

 

posted @ 2018-05-28 16:19  思之如狂  阅读(68)  评论(0)    收藏  举报