Java设计模式之单例模式

很多人都疑惑,单例模式是什么?为什么要用单例模式?在这里,笔者记录的仅仅只是自己对于知识点的理解,如果有错误的,请下方评论指教,共同进步,谢谢。

单例模式是什么?

简单理解: 单例就是一个实例被多个用户共享,好比宿舍共用同一个垃圾桶,这个垃圾桶就是单个实例,现实生活中不可能每个人都配一个垃圾桶什么的,那样太浪费资源了吧。

官方理解:对象的创建模式,确保某一个类只有一个实例,并且能够自动实例化且向整个应用程序提供这个实例。单例模式的核心在于通过一个接口返回唯一的对象实例;首要的问题就是要把创建实例的权限收回来,让类自身来负责自己类的实例的创建工作,然后由这个类来提供外部可以访问这个类实例的方法

单例模式的特点:

1、单例类只能有一个实例

2、单例类必须自己创建自己的实例(无法从外部创建,创建的时候将构造函数设置为私有的)

3、单例类必须向所有对象提供自己的实例

单例模式的优点:

1、在内存中只有一个对象,节省内存空间

2、避免频繁的创建销毁对象,提高性能

3、避免对共享资源的占用,可以全局访问

单例模式的类型:

1、饿汉单例(自动创建实例)

2、懒汉单例(调用的时候才创建实例)

3、登记式单例(这个我还没理解)

一、饿汉单例

//饿汉式单例,在类初始化的时候,已经自己实例化了
public class mvc {
private static mvc instance = new mvc(); private mvc() { } public static mvc getInstance(){ return instance; } }

饿汉在类创建的同时就已经创建好一个静态的对象供使用了,线程是安全的

二、懒汉单例

//懒汉单例,在第一次调用的时候实例化自己
public class mvc1 {
    private static mvc1 instance = null;
    private String name;
    private mvc1(){}
    //静态工厂方法
    synchronized public static mvc1 getInstance(){
        if(instance==null){
            instance = new mvc1();
        }
        return instance;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public void printinfo(){
        System.out.println("this name is "+name);
    }
}

测试代码
//定义测试类
public class testmvc1 {
    public static void main(String[] args) {
        mvc1 m2 = mvc1.getInstance();
        m2.setName("0539");
        mvc1 m1 = mvc1.getInstance();
        m1.setName("json");
        m1.printinfo();
        m2.printinfo();
        System.out.println(m1==m2?"创建的是同一个实例":"创建的不是同一个实例");
    }
}

结果

this name is json
this name is json
创建的是同一个实例

测试结果说明:实例化,结果往往是最后一个的实例。也就是说,单例模式,不管是饿汉还是懒汉,创建的都是同一个实例。
mvc1类必须要有一个 private 访问级别的构造函数,只有这样,才能确保单例不会在系统中的其他代码内被实例化,同时,在外部的话只能通过getInstance()方法去调用;
其次,instance 成员变量和 getInstance 方法必须是 static 的。
懒汉单例下是没有考虑线程安全问题的,所以要用synchronized加同步

饿汉和懒汉的区别:
1、饿汉自动实例化,懒汉要调用它才实例化
2、饿汉不用考虑线程安全问题,懒汉需要考虑线程安全问题

什么是线程安全?

如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。

或者说:一个类或者程序所提供的接口对于线程来说是原子操作,或者多个线程之间的切换不会导致该接口的执行结果存在二义性,也就是说我们不用考虑同步的问题,那就是线程安全的。

 

总结:

1、单例模式的作用是用来创建单个实例,并且这个实例这整个应用程序共享

2、单例模式的类型有三种:饿汉单例,懒汉单例,登记式单例

    其中饿汉自动创建实例,并保证线程安全;懒汉被动创建实例,不能保证线程安全的问题。

3、单例模式的优点:但同一个对象被多次实例,会占用大量资源,减少性能;通过采用单例,那么每次都是调用同一个实例,会提高性能。好比喝水,不可能每次都用一次性杯子。

 

posted @ 2016-09-06 16:35  书升  阅读(418)  评论(2编辑  收藏  举报