欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

设计模式之——单例模式

程序员文章站 2022-06-05 21:01:27
1 概念 一个类有且仅有一个实例,并且自行实例化向整个系统提供。 2 适用场景 一些资源管理器构件必须只有一个实例。 3 实现以及优缺点 单例优点:提供了对唯一实例的受控访问,由于在系统内存中只存在一个对象,因此可以节约系统资源。 单例缺点:在一定程度上违背了单一职责原则。 3.1 饿汉模式 优点: ......

1 概念

  一个类有且仅有一个实例,并且自行实例化向整个系统提供。

2 适用场景

  一些资源管理器构件必须只有一个实例。

3 实现以及优缺点

  单例优点:提供了对唯一实例的受控访问,由于在系统内存中只存在一个对象,因此可以节约系统资源。

  单例缺点:在一定程度上违背了单一职责原则。

3.1 饿汉模式

  优点:在类被初始化的时候就在内存中创建了对象,故线程安全。

  缺点:空间换时间

package singleton;

/**
 * 饿汉模式
 */
public class singletonone {
    private singletonone instance = new singletonone();

    private singletonone() {
    }

    private singletonone getinstance() {
        return instance;
    }
}

  

3.2 懒汉模式

  缺点:不用就不实例化,在方法被调用后才创建对象,在多线程下存在风险。为线程非安全方式。

package singleton;

/**
 * 懒汉模式
 */
public class singletontwo {
    private singletontwo instance;

    private singletontwo() {
    }

    private singletontwo getinstance() {
        if (null == instance) {
            return new singletontwo();
        }
        return instance;
    }
}

  

3.3 线程安全的懒汉式

  优点:线程安全。

  缺点:由于每次调用都需要进行同步,而且大部分情况下实例是已经创建成功了,造成了不必要的同步开销,不建议用这种方式。

package singleton;

/**
 * 线程安全的懒汉式
 */
public class singletonthree {
    private singletonthree instance;

    private singletonthree() {
    }

    private synchronized singletonthree getinstance() {
        if (null == instance) {
            return new singletonthree();
        }
        return instance;
    }
}

  

3.4 双重检查模式的懒汉式dcl

  该方法线程安全,声明为volatile实例对象,确保了多线程时的可见性,同时同步方法移步到代码块中,只有在该对象没有被实例化的时候才调用同步方法,节省了一部分开销。

  特点:其一为用volatile修饰类实例对象;其二同步代码块。

package singleton;

public class singletondcl {
  //volatile修饰的值,在线程独有的工作内存中,线程直接和主内存交互,如果修改,则主内存立即可见。 private volatile singletondcl instance = null;
  //私有构造器,使外部调用初始化时只能通过调用getinstance这个静态方法来获得实例。 private singletondcl() { } private singletondcl getinstance() { if (null == instance) //首先进行非空判断。
     { synchronized (singletondcl.class)//对整个类进行加锁,限制当前对象只能被一个线程访问
       { return new singletondcl(); } } return instance; } }

 

3.5 静态内部类单例模式

  特点:利用静态类只会加载一次的机制,由于在调用 singletonholder.instance 的时候,才会对单例进行初始化,故节省了内存开销。

package singleton;

/**
 * 线程安全静态内部类
 */
public class singletonstatic {
    private singletonstatic() {
    }

    public static class singletonholder {
        private static singletonstatic instance = new singletonstatic();
    }

    private singletonstatic getinstance() {
        return singletonholder.instance;
    }
}

  

4 举例实践

4.1 jdk runtime,饿汉模式

  java是单进程,由于一个java程序启动一个jvm进程,一个jvm进程对应一个runtime实例,使应用程序能够与其运行的环境相连接。

public class runtime {
    private static runtime currentruntime = new runtime();

    /**
     * returns the runtime object associated with the current java application.
     * most of the methods of class <code>runtime</code> are instance
     * methods and must be invoked with respect to the current runtime object.
     *
     * @return  the <code>runtime</code> object associated with the current
     *          java application.
     */
    public static runtime getruntime() {
        return currentruntime;
    }
}

  

4.2 logger

 

5.扩展

问:为什有私有构造器

答:防止外部构造者直接实例化对象。

问:对象在实例化过程中的操作实例化空间如何计算

答:首先了解存储区域,请参考jvm读书笔记