单例模式

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

//饿汉式
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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值