博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
singleton单例模式小结
阅读量:5257 次
发布时间:2019-06-14

本文共 2831 字,大约阅读时间需要 9 分钟。

1.饿汉模式

public class SingletonEntity2 {    // 在类加载的时候创建对象:饿汉模式    public static SingletonEntity2 obj = new SingletonEntity2();        // 构造方法私有化    private SingletonEntity2(){}        public static SingletonEntity2 getInstance(){        return obj;    }    }

2.懒汉模式

public class SingletonEntity {        // 静态变量存放在方法区中,类加载的时候赋值,而且只会赋值一次,懒汉模式    public static SingletonEntity obj = null;        // 构造方法私有化    private SingletonEntity() {}        // 对外提供获取实例的公开的静态的方法    public static SingletonEntity getInstance() {        if (obj == null) {            obj = new SingletonEntity();            System.out.println("新创建实例");        }        System.out.println("直接返回实例");        return obj;    }    }

3.测试类

public static void main(String[] args) {        SingletonEntity obj1 = SingletonEntity.getInstance();    SingletonEntity obj2 = SingletonEntity.getInstance();    System.out.println(obj1 == obj2); // true}

==========================================================================================================================================

懒汉模式不安全性测试:

1.起现成类:

public class RunnableThreadTest implements Runnable {        @Override    public void run() {                SingletonEntity obj = SingletonEntity.getInstance();        System.out.println(Thread.currentThread().getName()+" "+obj);      }}

2.测试类:

public class SingletonTest {    public static void main(String[] args) {                Thread thread1 = new Thread(new RunnableThreadTest());        Thread thread2 = new Thread(new RunnableThreadTest());        thread1.start();        thread2.start();            }}

3.运行结果:

Thread-0 com.beijing.singleton.SingletonEntity@406866f9Thread-1 com.beijing.singleton.SingletonEntity@25eb939e

==========================================================================================================================================

改善结果:推荐使用双检查锁机制

public class SingletonEntity {    // 静态变量存放在方法区中,类加载的时候赋值,而且只会赋值一次,懒汉模式    public static volatile SingletonEntity obj = null;    // 构造方法私有化    private SingletonEntity() {    }    // 对外提供获取实例的公开的静态的方法    public static SingletonEntity getInstance() {        try {            // 双检查所机制            if (obj == null) {                synchronized (SingletonEntity.class) {                    if (obj == null) {                        Thread.sleep(1000);                        obj = new SingletonEntity();                    }                }            }        } catch (Exception e) {            e.printStackTrace();        }        return obj;    }}
为什么要用volatile修饰instance?原因:在于instance = new SingletonEntity()的时候,在内存中实际上是分3步执行的:1)分配对象的内存空间:memory = allocate();2)初始化对象:ctorInstance(memory);3)指向分配的地址:instance =memory多线程在执行的时候,2 3可能发生重排序。即有可能线程A执行到第3步的时候,读取到instance不为null,就返回。实际上此时还未执行第二部即未初始化。加上volatile就可以避免2 3步重排序来保证线程安全。

 

转载于:https://www.cnblogs.com/zhangjianbing/p/8066526.html

你可能感兴趣的文章
【poj3690】Constellations 哈希
查看>>
2017年秋季个人阅读计划
查看>>
c++ class
查看>>
[leetcode]Longest Valid Parentheses
查看>>
Altera Quartus II 12.0订购版下载
查看>>
移动端踩坑系列(一)————input默认调用数字键盘
查看>>
第十八次ScrumMeeting会议
查看>>
mysql部分替换
查看>>
IOS关于数据加密(主要为登录加密)想总结的
查看>>
微信公众号导出关注的用户信息
查看>>
test
查看>>
使用ProGuard使你android代码保持混淆
查看>>
android listVIew实现button按钮监听程序
查看>>
[C++] getaddrinfo的一个bug
查看>>
perl C/C++ 扩展(四)
查看>>
BZOJ2763: [JLOI2011]飞行路线
查看>>
【c# 学习笔记】阻止派生类重写虚成员
查看>>
Django 路由
查看>>
fcgi返回状态码
查看>>
pycharm 中查找替换功能
查看>>