浅谈java单例模式——优点以及为什么使用到synchronized

来源:互联网 发布:信阳淘宝摄影e 编辑:程序博客网 时间:2024/06/05 11:36

首先

说一下单例模式的好处:减少系统资源的消耗.因为这种工具类基本上贯穿程序始终,必然会频繁调用.如果每一次调用都要重新生成实例,带来的就是 在内存堆中,分配一部分内存空间.所以这种模式会提高程序的运行速度,减少资源消耗。

可能对于没有理解单例模式的小伙伴来说,对这些好处理解不深。看完下面的解说后再感受一下

第一,单例模式的形式有两种 (饿汉式,懒汉式)
(1)饿汉式

class Single{     private static Single s = Single();    private Single(){//私有无参构造方法    }    private static Single s = Single();    {         return s;    } }

(2)懒汉式

class Single {    private static Single s = null;    private Single() {    }    public static Single getInstance() {        if (s == null) {//这里做判断是为了提高效率            synchronized (Single.class) {                if (s == null) {                    s = new Single();                }            }        }        return s;    }}

有看过java的单例模式的应该大多看到的是(2)懒汉式,因为它的效率更高。下面我们以懒汉式进行解说

第二,通过实例——垃圾回收站 说明单例模式
大家都知道电脑中的垃圾站是吧,大家无论删除了文件,图片,还是视频等等,都放在了垃圾回收站里。没有见过你删除了一个C盘中的某个文件,结果这个文件在D盘冒出来了吧,呵呵。这个垃圾回收站就是单例模式构造的,它自带删除操作,其他文件,图片,视频等只要想执行删除操作就调用它,然后这些删除的东西都放在垃圾箱里。所以当你删除了文件A,又删除文件B,打开垃圾回收站的时候,文件A和文件B都在里面。废话不多说,代码说事:

//垃圾回收站类public class Recycle{    private static Recycle rec = null;    private Recycle(){}    //获得对象的静态方法    public static Recycle getInstance(){        if(rec == null){            synchronized(Recycle.class){//同步锁                if(rec == null)                    rec = new Recycle();            }        }    }    //表示删除函数,这里模拟删除    public void delete(String thing){        System.out.println(thing);    }}

//删除文件类
public class DeleteFile{
Recycle recy = Recycle.getInstance();
recy.delete(“A已删除”);
}

//删除图片类
public class DeletePicture{
Recycle recy = Recycle.getInstance();
recy.delete(“B图片被删除”);
}

看了上面的例子,大家应该对单例模式有了一定的了解了吧,再结合它的好处思考一下,是不是有所收获。

第三,解释单例模式中的一些疑惑
(1)为什么用同步锁
因为在项目中如果有很大的并发量的情况下,有可能造成同时又多个程序执行这个类实例化的方法,因此我们需要在创建类实例化方法的时候添加同步执行。

(2)为甚懒汉模式中要使用两个if()判断对象是否为空
第一个判断,大家应该可以理解。关键是第二个if判断,大家会想第一个if不是已经判断出对象是否为空了吗? 现在我拿上面写的例子来解释一下,当DeleteFile(用x代替)和DeletePicture(用y代替)同时调用Recycle的对象时,此时rec为null,所以 x 和 y 都会经过第一个if判断,到达同步锁那里,其中一个(假设 x)进入到里面以后,y在锁(synchronized())外等候,x从锁里出来后,rec已经不为null,这时y进入锁后,如果没有if判断rec是否为空,是不是rec又执行了一次new操作,这样x 和 y都不是同一个对象了。

到这里,讲解就结束了,如有疑问,评论回复。

1 0