Java - 单例模式

  单例模式

是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中,

应用该模式的类一个类只有一个实例。即一个类只有一个对象实例

 

 

  单例定义 

数学与逻辑学中,singleton定义为“有且仅有一个元素的集合”。
单例模式最初的定义出现于《设计模式》(艾迪生维斯理, 1994):“保证一个类仅有一个实例,并提供一个访问它的全局访问点。”
Java中单例模式定义:“一个类有且仅有一个实例,并且自行实例化向整个系统提供。”

  

* 单例模式:确保某一个类,能产生一个实例
*
* 设计思路:
* 1, 将构造函数私有化,确保类外部不能使用new关键字自行创建对象
* 2, 在类的内部实例化一个对象,并通过静态方法返回

 

例:一个普通的单例类

class Singleton{

    private Singleton(){
        System.out.println("单例模式");
        
    }

 

 

 实现单例模式的方法:饿汉式单例、懒汉式单例、双重加锁的懒汉式单例模式、使用synchronized 同步类、使用静态内部类实现单例

注:由于实现单例的方法有很多,这也使得他们懂得优缺点也存在差异,这就需要我们在编写过程中选择合适的方法来运用的项目中去

接下来我们分别看一下实现代码:

  饿汉式单例: 

private static Singleton  sing = new Singleton();
    public static Singleton getIns(){
        return sing;
    }

  缺点:在类一加载时,就实例化对象,提前占用系统资源 

//对第一行static的一些解释
//java允许我们在一个类里面定义静态类。比如内部类(nested class)。
//把nested class封闭起来的类叫外部类。
//在java中,我们不能用static修饰顶级类(top level class)。
//只有内部类可以为static。

  懒汉式单例:

private static Singleton  sing = null;
    public static Singleton getIns(){
        
        if (sing==null) {
            sing = new Singleton();    
            }
        return sing;
}        

  优点:解决了懒汉式提前占用系统资源的问题

 

  使用synchronized 同步类

private static Singleton  sing = null;
    public static synchronized Singleton getIns(){
        
        if (sing==null) {
            sing = new Singleton();    
        }
        return sing;
}    

  synchronized :将一个方法或者代码块进行加锁,同一个时间只允许一个线程访问,对方法进行加锁,确保懒汉式单例,可以线程安全

  

  双重加锁的懒汉模式:只有第一次sing为null的时候才进行线程锁

private static Singleton  sing = null;
    public static Singleton getIns(){
        if(sing==null){
            synchronized(Singleton.class){
                if (sing==null) {
                    sing = new Singleton();    
                }
            }    
        }
        return sing;
}
 

   当后续sing不为null时就无需线城锁,可以允许多个线程同时拿走sing

//这个模式将同步内容下放到if内部,提高了执行的效率,不必每次获取对象时都进行同步,只有第一次才同步,创建了以后就没必要了。

//这种模式中双重判断加同步的方式,比第一个例子中的效率大大提升,因为如果单层if判断,在服务器允许的情况下,

//假设有一百个线程,耗费的时间为100*(同步判断时间+if判断时间),而如果双重if判断,100的线程可以同时if判断,理论消耗的时间只有一个if判断的时间。

//所以如果面对高并发的情况,而且采用的是懒汉模式,最好的选择就是双重判断加同步的方式。

 

   静态内部类实现单例:

private static class Singleton1{
        private static Singleton  sing = new Singleton();
    }
    public static Singleton getIns(){
        return Singleton1.sing;
    }

  优点:解决了饿汉式提前占用资源的问题,解决了懒汉式线程不安全的问题

 

 

 

 

 

 

posted on 2018-04-15 10:41  Code_任  阅读(257)  评论(0编辑  收藏  举报

导航