java 单例模式的一些个人见解和推荐写法

说说对单例模式的简单见解和推荐写法

先说说什么是单例模式吧?

   先说说自己的见解吧!我认为单例模式就是在程序生命周期内,在内存中指挥存在一个对象的实例。
  Java中单例模式定义:“一个类有且仅有一个实例,并且自行实例化向整个系统提供。” ----出处 单例模式

  先说说几种常见的单例模式的写法吧!

第一种懒汉模式:

public class Singleton{
    private static final Singleton INSTANCE = new Singleton();

    public static Singleton getInstance(){
        return INSTANCE;
    }

}

  优先:不存在多线线程问题,java的机制会保证对象在内存中只有一份。
  缺点:在类被加载的时候就直接初始话了,如果后面一直都使用的话就造成了内存浪费,如果初始比较消耗的话也会拖慢第一次加载。
  个人见解: 个人不太喜欢用这种方式,对象的初始化时间不太容易控制。
  推荐指数:
  单线程:★★☆☆☆
  多线程:★★☆☆☆

第二种饿汉模式:

public class Singleton{
    
    private static Singleton INSTANCE;

    public static Singleton getInstance(){
        if (INSTANCE == null){
            INSTANCE = new Singleton();
        }
        return INSTANCE;
    }

}

  优先:在第一次调用方法的时候才会构造对象,解决了饿汉模式的内存浪费,和初始化不确定的问题。
  缺点:在多线程情况下无法保证内存对象只有一个,有肯能在内存多同时存在多个。造成程序错误。
(原因:java的复制和构造对象无法保证是原子操作,所有在多线程中,如果一个线程刚好进入if内,还没有完成对象赋值,这是又有线程到了if判断内
,因为第一个还没有完成赋值操作,所有现在INSTANCE对象还为null,这是第二个线程也会取构造一个对象,这样就会在线程内形成多个对象。)
  个人见解:个人觉得这种方式的单例容易造成在多线程中的问题,不太推荐。
  推荐指数:
  单线程:★★★☆☆
  多线程:☆☆☆☆☆

第三种方法锁模式

这种模式就是在饿汉模式上在方法上加上方法锁

public class Singleton{

    private static Singleton INSTANCE;

    public static synchronized Singleton getInstance(){
        if (INSTANCE == null){
            INSTANCE = new Singleton();
        }
        return INSTANCE;
    }

}

  优先:解决了饿汉模式中多线程中可能造成程序错误的问题,也保留了延迟初始话的优点。
  缺点:每次调用方法都会先取获取锁,不管是不是在多线程或者有没有人在使用,都会需要获取锁,造成方法调用速度变慢。
  个人见解:这种方式还是不错的,解决了多线程问题,也做到了延迟初始化对象。唯一不足的地方就是每次调用方法,都需要获取锁,不是特别适合。
  推荐指数:
  单线程:★☆☆☆☆
  多线程:★★★☆☆

第四种检查锁模式

public class Singleton {

    private static Singleton INSTANCE;

    public static Singleton getInstance() {
        if (INSTANCE == null) {
            synchronized (Singleton.class) {
                if (INSTANCE == null) {
                    INSTANCE = new Singleton();
                }
            }
        }
        return INSTANCE;
    }

}

  优先:解决了每次调用方法都检查锁的问题,而且也保留了延迟初始化的有点
  缺点:实现稍微有点复制,而且不是很容易理解。
  个人见解:这是比较推荐的方式,这种方式解决了,上面几种方式中出现的问题。
  推荐指数:
  单线程:★★★★☆
  多线程:★★★★☆

第五种枚举模式

这种模式也许不太常见,但是的确存在这种方式,曾经在google的开源项目中发现过,个人认为还是不错的。这种方式和懒汉模式模式差不多吧

public enum Singleton {
    INSTANCE;
}

  优先:java的枚举会保证对象的唯一,唯一直接支持序列化的模式 ,而且还支持串行调用,天生只支持单个对象
  缺点:算是没有太大缺点
  个人见解:还不错的模式吧,比饿汉模式简单
  推荐指数:
  单线程:★★★★★
  多线程:★★★★★

第六种静态内部类模式

public class Singleton {

    public static Singleton getInstance(){
        return Holder.SIN;
    }

    private static class Holder{
        private static Singleton SIN = new Singleton();
    }
}

  优先:内部类保证了对象的延迟加载和对象的唯一性,只有在方法调用的时候才会被初始化,相比一检查锁模式有简单很多
  缺点:唯一的缺点就是会多加载一个类。
  个人见解:这种模式是个人最推荐的一种方,他保留了上面所以模式的优先,有把他们的缺点解决掉了。
  推荐指数:
  单线程:★★★★★
  多线程:★★★★★

Android 中的单例模式

额外在说说单例模式在Android中的一些应用和注意吧。

public class SingletonApplication extends Application {
    private static SingletonApplication SIN;

    @Override
    public void onCreate() {
        super.onCreate();
        SIN = this;
    }


    public static SingletonApplication getInstance(){
        return SingletonApplication.SIN;
    }
}

  这应该是Android最常见的一种应用了吧!Application 对象在Android天生就是单例模式,这种与其说这种方式是应用,还不如说是单例的一种应用还不如说是一种扩展吧!
  但是单例在Android有特别容易造成内存泄漏,好多时候如果把activity或者view等一些对象传给了单例对象引用
了有没有在activity等对象释放的时候取置空引用的话,那内存泄漏就发生了,所以在Android中使用单例模式的时候
需要特别注意。需要记得每次都去释放对象。
  比较推荐大家这样去持有一些容易造成泄漏的对象 WeakReference<Context> contextWeakReference;
适用弱引用的方式,这样就不会造成对象无法被回收了。

说在后面的话

  谢谢大家看,以上都是自己作为一个Android 和 java 开发的一些见解,希望对大家会有一点作用把,
如果一在这其中哪怕有一点收获我也会觉得非常的开心。后面也会写一些自己比较喜欢的东西。

links

作者
java 单例模式的一些个人见解和推荐写法
博客

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值