面试复现
面试官:懒汉式和饿汉式有什么不同?
你:饿汉式特点在于有实例的延迟加载
面试官:懒汉式延迟加载有没有什么问题?
你:懒汉式如果多线程访问时有线程安全问题,可以使用同步的方式来解决,同步代码块和同步代码函数都可以,但是同步代码函数稍微有点低效率,用同步代码块的双重判断的形式可以解决这个问题
面试官:加同步的时候使用的锁是哪一个?
你:该类所属的字节码文件对象
面试官:好了你对薪资有什么看法 (ヾ(≧▽≦*)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;
}
}
我们现在思考这么一种情况:
- 多线程并发访问getInstance(),A线程进行if判断后进入阻塞状态,此时B线程进行if判断后也进入阻塞状态
- 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;
}
}
本人个人网站: https://www.icnfox.cn 欢迎来访
有任何问题可以在个人网站的评论区留言,看到就会第一时间回复 啾咪ヾ(≧▽≦*)o