java设计模式:五、单例模式

来源:互联网 发布:苏联歌曲 知乎 编辑:程序博客网 时间:2024/05/21 05:05

单例模式

项目启动时,会有多个线程来访问。如果一个类是不能被改变的,如果不适用单例模式,每一个先知执行时创建一个对象。对象创建的多了,必然会引起内存泄漏。想想淘宝网站,双十一零点,几百万人访问淘宝,单个类,被创建了几百万次,即使内存不泄露,访问也会比较缓慢。
所以,应该尽可能把一些不能被改变的类,设计成单利模式。
单例模式和上面的工厂模式一样,如果引入了spring,基本已经被spring代替了。spring的注解@component如果不设置scope,即默认为单利的。

一、简单实现

最简单的单例模式实现方式,一共两步:
* 私有构造器
* 提供静态变量

public class Single{    private Single(){};    public static Single SINGLE = new Single();    //...其他方法}

这是最简单的一个单利模式的实现。也被称为饿汉式。即类被初始化的时候就把对象创建出来了。
它的优缺点:
- 优点

简单,不会存在多线程环境下,被创建多个对象的情况。
- 缺点
如果某个类很少被适用到,项目启动时就被创建了出来,这样会比较浪费内存。内存中白白存放一个不用的对象。

二、需要时创建

简单方式有了缺点,就有新的改进办法。即可以在它第一次被适用的时候来创建。

public class Single{    private Single single;    private Single(){};    public Single getInstance(){        if (single == null) {            single = new Single();        }        return single;    }    //...其他方法}

这样的话,即能在被第一次使用的时候被创建。但是这样同样具有一个问题,多线程环境下面,如果存在并发情况,将会创建多个对象。
A线程进来,调用getInstance()方法,发现single为null,正要准备创建对象。
B线程进入,发现single也为null。也要创建对象。
这样的话,即创建了两个对象。解决方法是在这儿创建时,增加同步情况。

public class Single{    private Single single;    private Single(){};    public Single getInstance(){        if (single == null) {            synchronized (Single.class) {                single = new Single();            }        }        return single;    }    //...其他方法}

同步方法将会比较慢,虽然说只是在第一次使用的时候才会出现。不过还有一种写法是,提供静态内部类。内部类创建是同步的。

public class Single{    private Single(){};    private static class SingleHolder {        private static Single single = new Single();    }    public Single getInstance(){        return SingleHolder.single;    }    //...其他方法}

上面是单例模式的几种实现方法。

原创粉丝点击