每天一个面试题,有手就能学废,大家好,我是爱码士赵Sir!
1、什么是单例模式
单例设计模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点
就是这个类只能有一个对象,不能乱搞,然后通过一个方法能拿到它。
2、应用场景
全局管理类自己封装的SharedPreferencesManager,比如Okhttp中的okhttpclient也最好要保证全局单例,免得多次初始化浪费资源与性能,还有腾讯的bugly里面的CrashReport,CrashModule,还比如Fresco初始化 JavaWeb数据库的连接池
3、实现步骤
1、构造方法私有化,私有化了之后,外部就不会通过new的方式来产生它的实例了,
2、声明一个本类对象,自己要生成一个对象,让别人去用
3、给外部提供一个静态方法获取对象实例,静态的方法可以不用实例化对象就可以调用,直接用类名 直接去调用
4、实现的方式
1、饿汉式:对象的生命周期比较长,在声明本类对象的时候,直接new 一个实例,占用内存时间长,提高效率
//饿汉式 在类被加载后,对象被创建到程序结束后释放
class Singleton{
//构造方法私有化
private Singleton(){}
//声明一个本类的对象
private static Singleton singleton=new Singleton();
//提供一个静态方法获取对象实例
public static Singleton getInsatance(){
return singleton;
}
}
2、懒汉式 对象的生命周期比较短,在第一次调用getInstance方法时才会new一个对象供外部调用,占用内存时间短,第一次使用时,效率稍低点
建议大家用懒汉式,懒加载延迟加载
//懒汉式第一次调用getInstance方法时
class Singleton{
//构造方法私有化
private Singleton(){}
//声明一个本类的对象
private static Singleton singleton;
//提供一个静态方法获取对象实例
public static Singleton getInsatance(){
if(singleton==null){
singleton==new Singleton();
}
return s;
}
}
上面的demo 在多线程访问的时候,会有安全问题,会有可能产生多个实例,多线程情况下的单例,怎么实现呢?大佬们在评论区留言!
更新!等了好多天也没见你们留言!只能我来更新一下!=========

- 先来看第一种方法
public class Singleton {
private static Singleton singleton=null;
private Singleton(){
}
public static synchronized Singleton getInstance(){
if(singleton==null){
singleton=new Singleton();
}
return singleton;
}
}
我们采用线程同步块的方法给这个getInstance加一个锁,这种方法虽然保证了线程安全,但是每一次调用的时候都会执行getInstance方法,每一次都去拿锁,执行方法的开销会增大,咱们能不能只是在创建的时候加锁呢!就是说我们不需要在每次调用的时候线程去竞争,只需要在new 操作的时候线程去竞争,所以第二版就来了
//这种写法是不能保证线程安全的
public static Singleton getInstance(){
if(singleton==null){
synchronized (Singleton.class){
singleton=new Singleton();
}
}
return singleton;
}
你只锁住了new 操作,但是还会产生多个对象的,因为很有可能多个线程同时获取的singleton==null,进到if里边然后多个线程进行排队去执行synchronized代码快里边的内容,还是会进行多次的new!所以我们需要再加一层判断!
public static Singleton getInstance(){
if(singleton==null){
synchronized (Singleton.class){
if(singleton==null){
singleton=new Singleton();
}
}
}
return singleton;
}
这种写法才是既是线程安全的,又是最节省性能的写法!学废了么
5、单例的优点
1、在设计一些工具类的时候(通常工具类只有功能方法,没有属性)
2、工具类可能会被频繁调用
3、目的是为了节省重复创建对象所带来的内存消耗,从而提高效率
能不能使用构造方法私有化+静态方法来代替单例?
//使用构造方法私有化+静态方法 来实现工具类 比如JDK里的Math函数class Tools{ priavte Tools(){ } public static void print(){ }} 这种实现方式,所有的方法都是静态的,方法里的临时变量都会存在方法区而单例模式的方法依赖于对象,可以不是静态的,执行方法的时候会入栈然后创建临时变量,方法执行完毕会出栈临时变量会 销毁,这样比的话,单例模式的内存开销比构造方法私有化加静态方法实现要小
你学废了么!么么哒么么哒么么么么哒!