本网站(662p.com)打包出售,且带程序代码数据,662p.com域名,程序内核采用TP框架开发,需要联系扣扣:2360248666 /wx:lianweikj
精品域名一口价出售:1y1m.com(350元) ,6b7b.com(400元) , 5k5j.com(380元) , yayj.com(1800元), jiongzhun.com(1000元) , niuzen.com(2800元) , zennei.com(5000元)
需要联系扣扣:2360248666 /wx:lianweikj
Android 单例模式的四种实现方式
飘飘悠悠 · 275浏览 · 发布于2021-06-09 +关注

单例模式作为设计模式之一,使用场景非常多。本文讲述了Android实现单例模式的几种方式

目录

  • 一.饿汉式

  • 二.懒汉式

  • 三.双重检查加锁方式

  • 四.静态内部类方式

  • 总结

 

一.饿汉式

1

2

3

4

5

6

7

8

9

10

11

12

public class SingletionStarving {


    private static final SingletionStarving mInstance = new SingletionStarving();


    private SingletionStarving() {


    }


    public static SingletionStarving getInstance() {

        return mInstance;

    }

}

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

  • 声明静态对象时就初始化

  • static关键字修饰,静态变量,存储在内存中,只有一份数据。

  • final关键字,只初始化一次,所以mInstance实例只有一个。

 

二.懒汉式

1

2

3

4

5

6

7

8

9

10

11

12

13

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都会同步一次,浪费资源

 

三.双重检查加锁方式

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

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)

缺点

1

2

3

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关键字

1

private volatile static Singletion mInstance;

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

1

2

3

4

5

6

7

8

9

10

11

12

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之前的代码中。

 

四.静态内部类方式

1

2

3

4

5

6

7

8

9

10

11

12

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下vulkan与opengles纹理互通

talkchan · 1173浏览 · 2020-11-23 10:37:39
Android 使用RecyclerView实现轮播图

奔跑的男人 · 2171浏览 · 2019-05-09 17:11:13
微软发布新命令行工具 Windows Terminal

吴振华 · 866浏览 · 2019-05-09 17:15:04
Facebook 停止屏蔽部分区块链广告

· 752浏览 · 2019-05-09 17:20:08
加载中

0评论

评论
分类专栏
小鸟云服务器
扫码进入手机网页