java设计模式之单例模式——懒汉式(饱汉式)及多线程debug

1、懒汉式定义:

懒汉式设计模式:比较懒,在类创建时不创建对象,而是以延迟加载的方式,当需要使用时才创建。

2、懒汉式的优缺点:

3、懒汉式的基础创建方式:

package com.zxl.design.zxl.design.pattern.singleton;

/**
 * Created by Administrator on 2019/6/16.
 * 懒汉式是指初始化时是不创建的,在运行时延迟加载。
 * 单线程时没问题,但是多线程时会出现问题
 *
 */
public class LazySingleton {
    /**
     * 初级懒汉式单例设计模式
     * 线程不安全的,单线程时不会出问题,但是多线程时会出问题
     * 假设两个线程同时运行,第一个线程在判断完if (lazySingleton == null)为true,
     * 进入到方法内,但是还未执行创建对象或者还未执行完创建对象的步骤时,
     * 此时lazySingleton 还是null,第二个线程刚好走到判断是否为null时,则判断为null,
     * 之后线程二也会进入该方法。这样两个线程都进入,则都会正常创建对象, 造成创建两个对象。
     *即使最后lazySingleton返回的对象一样(因为lazySingleton被赋值两次,后一次将前一次覆盖)
     * 也同样是存在安全隐患。
     * */
    private static LazySingleton lazySingleton = null;
    private LazySingleton(){

    }
    public static LazySingleton getInstance(){
        if (lazySingleton == null){
            lazySingleton = new LazySingleton();
        }
        return lazySingleton;
    }

1)该类的基本使用方案:

package com.zxl.design.zxl.design.pattern.singleton;

/**
 * Created by Administrator on 2019/6/16.
 */
public class Test {
    public static void main(String[] args) {
        //该方案为单例模式,证明目前没有问题,
        //因为LazySingleton的构造方法私有,外部无法调用,所以
        //只能通过提供的公共访问方法构建。注:大家习惯用getInstance()这个方法名
        //但并不是必须的。建议可读性好,一般用该方法名
        //该测试方案通过debug的方式可以说明,类加载时是没有创建对象的,
        //等到使用该类时,才创建了对象,也就是所说的延迟加载。
        LazySingleton lazySingleton = LazySingleton.getInstance();
        System.out.print("program end");
    }
}

2)如何验证该方案存在问题呢?

我们要创建一个多线程的环境,通过debug方式手动控制其运行节奏,模拟该可能性。

 首先创建一个线程类(后面还会用到),在其中通过不安全的懒汉式创建一个对象。并打印线程的名字和它的值

然后测试类中创建两个线程,并开启。具体如下:

package com.zxl.design.zxl.design.pattern.singleton;

import java.net.SocketPermission;

/**
 * Created by Administrator on 2019/6/23.
 */
public class T implements Runnable {
    public void run() {
        LazySingleton lazySingleton = LazySingleton.getInstance();
        System.out.println(Thread.currentThread().getName() +" "+ lazySingleton);
    }
}
package com.zxl.design.zxl.design.pattern.singleton;

/**
 * Created by Administrator on 2019/6/16.
 */
public class Test {
    public static void main(String[] args) {
//        //该方案为单例模式,证明目前没有问题,
//        //因为LazySingleton的构造方法私有,外部无法调用,所以
//        //只能通过提供的公共访问方法构建。注:大家习惯用getInstance()这个方法名
//        //但并不是必须的。建议可读性好,一般用该方法名
//        //该测试方案通过debug的方式可以说明,类加载时是没有创建对象的,
//        //等到使用该类时,才创建了对象,也就是所说的延迟加载。
//        LazySingleton lazySingleton = LazySingleton.getInstance();
//        System.out.print("program end");
        Thread t1 = new Thread(new T());
        Thread t2 = new Thread(new T());
        t1.start();
        t2.start();
        System.out.print("program end");

    }
}

在如上不加干预的情况下,看最终运行的结果,好像是没问题的,但是在多线程中呢?

"D:\Program Files\Java\jdk1.8.0_102\bin\java" -agentlib:jdwp=tran
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值