设计模式之单例

设计模式之单例

单例模式:确保一个类只有一个实例并提供一个对它的全局访问指针

什么是线程安全?

如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。 
或者说:一个类或者程序所提供的接口对于线程来说是原子操作,或者多个线程之间的切换不会导致该接口的执行结果存在二义性,也就是说我们不用考虑同步的问题,那就是线程安全的。

懒汉式单例

    public class Singleton {  
       private Singleton() {}  
       private static Singleton single=null;  

       public static Singleton getInstance() {  
        if (single == null) {    
           single = new Singleton();  
         }    
        return single;  
      }  
    } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

懒汉式只有在调用getInstance的时候,才回去初始化这个单例,它是线程不安全的,并发环境下很可能出现多个Singleton实例,要实现线程安全,有以下三种方式,都是对getInstance这个方法改造,保证了懒汉式单例的线程安全

在getInstance方法上加同步

    public class Singleton {  
       private Singleton() {}  
       private volatile static Singleton single=null;  

       public synchronized static Singleton getInstance() {  
        if (single == null) {    
           single = new Singleton();  
         }    
        return single;  
      }  
    } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

双重检查锁定

    public class Singleton {  
       private Singleton() {}  
       private volatile static Singleton single=null;  

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

静态内部类

    public class Singleton {    
        private static class LazyHolder {    
           private static final Singleton INSTANCE = new Singleton();    
        }    
        private Singleton (){}    
        public static final Singleton getInstance() {    
           return LazyHolder.INSTANCE;    
        }    
    } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

饿汉式单例

    public class Singleton {  
        private Singleton() {}  
        private static final Singleton single = new Singleton();  

        public static Singleton getInstance() {  
            return single;  
        }  
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

饿汉式在类创建的同时就已经创建好一个静态的对象供系统使用,所以线程安全

枚举

public enum Singleton{
    INSTANCE;
    public void Singleton(){
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

这个思想直接源于Joshua Bloch的《Effective Java》(《Java高效编程指南》),不仅能避免多线程同步问题,而且还能防止反序列化重新创建新的对象

posted @ 2016-11-24 19:55  天涯海角路  阅读(106)  评论(0)    收藏  举报