cnfox

同步代码块解决单例懒汉式线程安全问题
面试复现 面试官:懒汉式和饿汉式有什么不同? 你:饿汉式特点在于有实例的延迟加载 面试官:懒汉式延迟加载有没有什么...
扫描右侧二维码阅读全文
09
2019/09

同步代码块解决单例懒汉式线程安全问题

面试复现

面试官:懒汉式和饿汉式有什么不同?

你:饿汉式特点在于有实例的延迟加载

面试官:懒汉式延迟加载有没有什么问题?

你:懒汉式如果多线程访问时有线程安全问题,可以使用同步的方式来解决,同步代码块和同步代码函数都可以,但是同步代码函数稍微有点低效率,用同步代码块的双重判断的形式可以解决这个问题

面试官:加同步的时候使用的锁是哪一个?

你:该类所属的字节码文件对象

面试官:好了你对薪资有什么看法 (ヾ(≧▽≦*)o 内心OS)

 哈哈哈以上纯属个人脑补,但是这么一个简单的知识点就有N多的考点,还是比较值的注意一下的,我们简单实现下以上对话的代码

代码实现

饿汉式做对比

package cn.icnfox.Java;

public class Single
{
    private static final Single s = new Single();
    private Single(){}
    public static Single getInstance()
    {
        return s;
    }
}

懒汉式

package cn.icnfox.Java;

public class Single
{
    private static Single s = null;
    private Single(){}


    public static  Single getInstance()
    {

     if(s==null)
        s = new Single();
         return s;
    }
}

 我们现在思考这么一种情况:

  1. 多线程并发访问getInstance(),A线程进行if判断后进入阻塞状态,此时B线程进行if判断后也进入阻塞状态
  2. A线程可运行后执行了一次s = new Single(); B线程可运行后又执行了一次s = new Single();

 此时就出现了一个问题,没有办法保证单例懒汉式的对象唯一性,懒汉式在多线程访问时产会有安全隐患,我们使用同步代码函数可以解决这个问题

package cn.icnfox.Java;

public class Single
{
    private static Single s = null;
    private Single(){}


    public static synchronized Single getInstance()
    {

     if(s==null)
        s = new Single();
         return s;
    }
}

 但是由此又产生了一个问题,就是多线程访问的时候,每个线程想获取实例都需要判断一次锁,所以加同步会比较低效,最终我们使用同步代码块并且引入双重判断来解决这个问题.

package cn.icnfox.Java;

public 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;
    }
}

Photo by Max Letek on Unsplash

Last modification:October 30th, 2019 at 08:56 am
如果觉得我的文章对你有用,请随意赞赏

Leave a Comment