单例模式

来源:互联网 发布:linux shell wait命令 编辑:程序博客网 时间:2024/06/11 12:00

面试中经常会被问单例模式,下面就简单说下解决方案

//饿汉式class Single{    private static  final Single s = new Single();    private Single(){}    public static Single getInstance()    {        return s;    }}/*私有化构造器,是为了不让其他的类去创建对象,而其他的类需要这个对象,那就使用提供的接口getInstance()方法返回这个单例对象,那现在谈下private static  final Single s = new Single();这个行代码的个人简介,私有化private,是不让其他的对象访问,静态static,只创建一次,但这个final是最难生活清楚的,常见的说法是为了不被改动(线程1在访问这个对象,而线程2去改变他,name线程1得到的结果就会出问题),但是我不理解,没有对外提供访问接口,如何能被改动?直到看到这个说法“在构造函数内对一个final域的写入,与随后把这个被构造对象的引用赋值给一个引用变量,这两个操作之间不能重排序。初次读一个包含final域的对象的引用,与随后初次读这个final域,这两个操作之间不能重排序。 ”,这里我才信服,final的作用,因为第一次new对象,可能回引起的问题。*/

懒汉式的单例模式

//懒汉式。class Single{    private static volatile Single s = null;    private Single(){}    /*    并发访问会有安全隐患,所以加入同步机制解决安全问题。    但是,同步的出现降低了效率。    可以通过双重判断的方式,解决效率问题,减少判断锁的次数。    */    public static  Single getInstance()    {        if(s==null)/*减少判定锁的过程,这个是可以少的,存在,只是为了优化去判断锁的过程,当对象存在,直接返回,连锁都不用拿*/        {            synchronized(Single.class)            {                if(s==null)/*实际去盘定锁是否存在,这个是必须存在,当两个线程同时到外层if中,没有这个,就会创建单例对象,违背单例的初衷*/                    s = new Single();            }        }        return s;    }}/*使用 volatile 有两个功用:1)这个变量不会在多个线程中存在复本,直接从内存读取。2)这个关键字会禁止指令重排序优化。也就是说,在 volatile 变量的赋值操作后面会有一个内存屏障(生成的汇编代码上),读操作不会被重排序到内存屏障之前。这个也就是做上面的饿汉式的final作用但是,这个事情仅在Java 1.5版后有用,1.5版之前用这个变量也有问题,因为老版本的Java的内存模型是有缺陷的。*/

个人简介及汲取别人的优点,下面是大神的讲解http://blog.csdn.net/haoel/article/details/4028232

原创粉丝点击