欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android 单例模式的四种实现方式

程序员文章站 2022-03-08 15:27:39
一.饿汉式public class singletionstarving { private static final singletionstarving minstance = new si...

一.饿汉式

public class singletionstarving {

    private static final singletionstarving minstance = new singletionstarving();

    private singletionstarving() {

    }

    public static singletionstarving getinstance() {
        return minstance;
    }
}
  • 构造函数用private修饰,外部无法访问
  • 声明静态对象时就初始化
  • static关键字修饰,静态变量,存储在内存中,只有一份数据。
  • final关键字,只初始化一次,所以minstance实例只有一个。

二.懒汉式

public class singletionslacker {

    private static singletionslacker minstance;

    private  singletionslacker() {}

    public static synchronized singletionslacker getinstance() {
        if (minstance == null) {
            minstance = new singletionslacker();
        }
        return minstance;
    }
}
  • 构造函数用private修饰,外部无法访问
  • 使用的时候即调用getinstance的时候才初始化
  • static关键字修饰,静态变量,存储在内存中,只有一份数据。
  • synchronized线程安全,多线程情况下单例的唯一性
  • 缺点:没次调用getinstance都会同步一次,浪费资源

三.双重检查加锁方式

网上建议和使用最多的方法

public class singletion {

    private static singletion minstance;

    private singletion() {}

    public static singletion getminstance() {
        if (minstance == null) {
            synchronized (singletion.class) {                if (minstance == null) {
                    minstance = new singletion ();                }
            }
        }
        return minstance;
    }
}
  • 构造函数用private修饰,外部无法访问
  • 使用的时候即调用getinstance的时候才初始化
  • static关键字修饰,静态变量,存储在内存中,只有一份数据
  • synchronized线程安全,多线程情况下单例的唯一性
  • 两次判断空,避免多次同步(synchronized)

缺点

private static singletion minstance;
private singletion() {}
public static singletion getminstance() {}

由于jvm特性,允许乱序执行,上面三句代码顺序不定,那么就可能出现失效的问题。
步骤一、倘若a线程执行getminstance(),还没执行构造方法singletion()
步骤二、此时b线程调用getminstance()。因为a已经执行getminstance(),所以minstance不为空就直接获取。
步骤三、由于b直接获取,而真实情况是a线程构造方法还未执行,所以minstance就为空了。
虽然此情况发生概率较小,但也是一种情况。为了解决这种情况,java1.6开始加入volatile关键字

private volatile static singletion minstance;

这样就避免了方式失效的情况。虽然会volatile消耗一些性能,所以最佳写法

public class singletion {

    private volatile static singletion minstance;
    private singletion () {}
    public static singletion getminstance() {        if (minstance == null) {
            synchronized (singletion.class) {                if (minstance == null) {
                    minstance = new singletion();                }
            }
        }
        return minstance;
    }
}

虽然volatile让方式完美,但是没有volatile关键字的写法基本能满足绝大部分情况。除非你要运行在高并发,或者java1.6之前的代码中。

四.静态内部类方式

public class singletioninternalclass {

    private singletioninternalclass() {}

    public static singletioninternalclass getinstance() {
        return singletioninternalclassholder.instance;
    }

    private static class singletioninternalclassholder {
        private static final singletioninternalclass instance = new singletioninternalclass();
    }
}

构造函数用private修饰,外部无法访问

使用的时候即调用getinstance的时候才初始化

调用getinstance才回去加载singletioninternalclassholder类,确保了线程安全,保证了单例的唯一性

总结

单例模式不管用那种方式实现,核心思想都相同
1、构造函数私有化,通过一次静态方法获取一个唯一实例
2、线程安全

最后推荐使用文中**双重锁方式和静态内部类的方式**来创建单例模式。

以上就是android 单例模式的四种实现方式的详细内容,更多关于android 单例模式的实现的资料请关注其它相关文章!