设计模式课程 设计模式精讲 8-2 单例设计模式-懒汉式及多线程Debug实战

1    主要内容

1.1  多线程debug

1.2  synchronized同步锁的调用

1.3  懒加载的应用

2    代码演练

2.1  单线程调用

2.2  多线程调用

2.3  锁的调用

1    主要内容
1.1  多线程debug

a  主要是在idea中,右键选择断点,选中thread,done即可。

b  使用的时候,frames选择下拉框,选择要执行的线程即可。

c  如下图所示

1.2  synchronized同步锁的调用

 如2.3所示

 如果锁放在静态方法上,锁的是整个class文件,如果放在非静态方法上,锁的是在堆内存中生成的对象。

详情参考 :https://blog.csdn.net/wagnteng/article/details/80529758

syncronized同步锁有加锁和开锁的开销,比较消耗资源,对性能有一定的影响。

1.3  懒加载的应用

外部类调取LazySingleton的时候才会进行初始化,所以实现了懒加载。

2    代码演练
2.1  单线程调用

测试类:

package com.geely.design.pattern.creational.singleton;

public class Test {

    public static void main(String [] args){
        //这样写异常,因为构造方法私有
//        LazySingleton lazySingleton = new LazySingleton();
       LazySingleton lazySingleton = LazySingleton.getInstance();
       System.out.println(lazySingleton);
    }
}

实体类:

package com.geely.design.pattern.creational.singleton;

public class LazySingleton {
    /*
    属性私有,其他外部类,无法调用该属性,安全
     */
    private static LazySingleton lazySingleton = null;

    /**
     * 构造方法私有,其他类无法实例化该类
     */
    private LazySingleton(){
    }

    /**
     * 这里写静态方法:因为外部类无法实例化创建出该类,
     * 只能通过该类的静态方法获取到该类。
     * @return
     */
    public static LazySingleton getInstance(){
        if(lazySingleton == null){
            lazySingleton = new LazySingleton();
        }
        return lazySingleton;
    }
}

打印结果:

"C:Program FilesJavajdk1.7.0_79injava.exe" "-javaagent:D:javadevolopKitideaanZhIntelliJ IDEA Community Edition 2018.1.4libidea_rt.jar=3988:D:javadevolopKitideaanZhIntelliJ IDEA Community Edition 2018.1.4in" -Dfile.encoding=UTF-8 -classpath "C:Program FilesJavajdk1.7.0_79jrelibcharsets.jar;C:Program FilesJavajdk1.7.0_79jrelibdeploy.jar;C:Program FilesJavajdk1.7.0_79jrelibextaccess-bridge-64.jar;C:Program FilesJavajdk1.7.0_79jrelibextdnsns.jar;C:Program FilesJavajdk1.7.0_79jrelibextjaccess.jar;C:Program FilesJavajdk1.7.0_79jrelibextlocaledata.jar;C:Program FilesJavajdk1.7.0_79jrelibextsunec.jar;C:Program FilesJavajdk1.7.0_79jrelibextsunjce_provider.jar;C:Program FilesJavajdk1.7.0_79jrelibextsunmscapi.jar;C:Program FilesJavajdk1.7.0_79jrelibextzipfs.jar;C:Program FilesJavajdk1.7.0_79jrelibjavaws.jar;C:Program FilesJavajdk1.7.0_79jrelibjce.jar;C:Program FilesJavajdk1.7.0_79jrelibjfr.jar;C:Program FilesJavajdk1.7.0_79jrelibjfxrt.jar;C:Program FilesJavajdk1.7.0_79jrelibjsse.jar;C:Program FilesJavajdk1.7.0_79jrelibmanagement-agent.jar;C:Program FilesJavajdk1.7.0_79jrelibplugin.jar;C:Program FilesJavajdk1.7.0_79jrelib
esources.jar;C:Program FilesJavajdk1.7.0_79jrelib
t.jar;F:xiangmu3XinIdeadesign_pattern	argetclasses" com.geely.design.pattern.creational.singleton.Test
com.geely.design.pattern.creational.singleton.LazySingleton@109d3f8b

Process finished with exit code 0
2.2  多线程调用

测试类:

package com.geely.design.pattern.creational.singleton;

public class Test {

    /*public static void main(String [] args){
        //这样写异常,因为构造方法私有
//        LazySingleton lazySingleton = new LazySingleton();
       LazySingleton lazySingleton = LazySingleton.getInstance();
       System.out.println(lazySingleton);
    }*/

    public static void main(String [] args){
        Thread thread1 = new Thread(new T());
        Thread thread2 = new Thread(new T());
        thread1.start();
        thread2.start();
        System.out.println("结束了!!!");
    }
}

线程类:

package com.geely.design.pattern.creational.singleton;

/**
 * 注:该类为线程类,调用LazySingleton
 */
public class T implements Runnable{

    @Override
    public void run() {
        LazySingleton lazySingleton = LazySingleton.getInstance();
        System.out.println(Thread.currentThread().getName()+"==="+lazySingleton);

    }
}

实体类:

package com.geely.design.pattern.creational.singleton;

public class LazySingleton {
    /*
    属性私有,其他外部类,无法调用该属性,安全
     */
    private static LazySingleton lazySingleton = null;

    /**
     * 构造方法私有,其他类无法实例化该类
     */
    private LazySingleton(){
    }

    /**
     * 这里写静态方法:因为外部类无法实例化创建出该类,
     * 只能通过该类的静态方法获取到该类。
     * @return
     */
    public static LazySingleton getInstance(){
        if(lazySingleton == null){
            lazySingleton = new LazySingleton();
        }
        return lazySingleton;
    }


}

打印日志1:

"C:Program FilesJavajdk1.7.0_79injava.exe" -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:4375,suspend=y,server=n -javaagent:C:Usersweijingli.IdeaIC2018.1systemcaptureAgentdebugger-agent.jar=file:/C:/Users/weijingli/AppData/Local/Temp/capture.props -Dfile.encoding=UTF-8 -classpath "C:Program FilesJavajdk1.7.0_79jrelibcharsets.jar;C:Program FilesJavajdk1.7.0_79jrelibdeploy.jar;C:Program FilesJavajdk1.7.0_79jrelibextaccess-bridge-64.jar;C:Program FilesJavajdk1.7.0_79jrelibextdnsns.jar;C:Program FilesJavajdk1.7.0_79jrelibextjaccess.jar;C:Program FilesJavajdk1.7.0_79jrelibextlocaledata.jar;C:Program FilesJavajdk1.7.0_79jrelibextsunec.jar;C:Program FilesJavajdk1.7.0_79jrelibextsunjce_provider.jar;C:Program FilesJavajdk1.7.0_79jrelibextsunmscapi.jar;C:Program FilesJavajdk1.7.0_79jrelibextzipfs.jar;C:Program FilesJavajdk1.7.0_79jrelibjavaws.jar;C:Program FilesJavajdk1.7.0_79jrelibjce.jar;C:Program FilesJavajdk1.7.0_79jrelibjfr.jar;C:Program FilesJavajdk1.7.0_79jrelibjfxrt.jar;C:Program FilesJavajdk1.7.0_79jrelibjsse.jar;C:Program FilesJavajdk1.7.0_79jrelibmanagement-agent.jar;C:Program FilesJavajdk1.7.0_79jrelibplugin.jar;C:Program FilesJavajdk1.7.0_79jrelib
esources.jar;C:Program FilesJavajdk1.7.0_79jrelib
t.jar;F:xiangmu3XinIdeadesign_pattern	argetclasses;D:javadevolopKitideaanZhIntelliJ IDEA Community Edition 2018.1.4libidea_rt.jar" com.geely.design.pattern.creational.singleton.Test
Connected to the target VM, address: '127.0.0.1:4375', transport: 'socket'
结束了!!!
Thread-0===com.geely.design.pattern.creational.singleton.LazySingleton@3eea8847
Disconnected from the target VM, address: '127.0.0.1:4375', transport: 'socket'
Thread-1===com.geely.design.pattern.creational.singleton.LazySingleton@3eea8847

Process finished with exit code 0

打印日志2:

Connected to the target VM, address: '127.0.0.1:4782', transport: 'socket'
结束了!!!
Thread-1===com.geely.design.pattern.creational.singleton.LazySingleton@28fa1b85
Thread-0===com.geely.design.pattern.creational.singleton.LazySingleton@57f4ea9d
Disconnected from the target VM, address: '127.0.0.1:4782', transport: 'socket'

Process finished with exit code 0
2.3  锁的调用

优点:解决了多线程懒加载初始化的问题。

缺点: 多线程的时候,由于一个线程被锁,其他的线程无法访问该类,被堵塞。性能大大降低

方法1:

package com.geely.design.pattern.creational.singleton;

public class LazySingleton {
    /*
    属性私有,其他外部类,无法调用该属性,安全
     */
    private static LazySingleton lazySingleton = null;

    /**
     * 构造方法私有,其他类无法实例化该类
     */
    private LazySingleton(){
    }

    /**
     * 这里写静态方法:因为外部类无法实例化创建出该类,
     * 只能通过该类的静态方法获取到该类。
     * @return
     */
    public static synchronized LazySingleton getInstance(){
        if(lazySingleton == null){
            lazySingleton = new LazySingleton();
        }
        return lazySingleton;
    }


}

方法2:

      public static LazySingleton getInstance(){
          synchronized (LazySingleton.class){
              if(lazySingleton == null){
                  lazySingleton = new LazySingleton();
              }
          }
          return lazySingleton;
    }
原文地址:https://www.cnblogs.com/1446358788-qq/p/11365927.html