单例模式(懒汉式与饿汉式),新增有关线程安全部分的介绍

一、饿汉式实现模式,在声明单例类的对象的时候,就 new (这种实现比较简单)

代码实现:

package com.liwei.singleton;

/**
 * 此单例模式是饿汉模式 关键点:1、构造方法私有化 2、提供一个对外访问的方法 3、饿汉模式是声明属性的时候,就实例化了
 * 
 * @author Administrator
 * 
 */
public class Singleton {

    // 饿汉式就是先 new 对象
    // 1、定义一个本类对象并实例化(饿汉式)
    private static Singleton instance = new Singleton();

    // 2、构造方法私有化
    private Singleton() {
    }

    // 3、给外部提供一个静态方法用于获取对象实例
    public static Singleton getInstance() {
        return instance;
    }
}

测试代码:

  /**
     * 饿汉模式的测试
     */
    @Test
    public void test() {
        // 不管你调用多少次这个方法,都返回的是同一个对象
        Singleton s1 = Singleton.getInstance();
        Singleton s2 = Singleton.getInstance();
        System.out.println(s1.hashCode());
        System.out.println(s2.hashCode());
        // 同一个对象,内存地址指向同一个
        System.out.println(s1 == s2);
    }

二、懒汉式实现模式,在 getInstance 方法,即真正须要用到这个单例类对象的时候,才去 new 

下面是懒汉式单例模式的实现类:

package com.liwei.singleton;

public class Singleton2 {
    private static Singleton2 instance;
    
    private Singleton2() {
    }
    
    public static Singleton2 getInstance(){
        if(instance == null){
            instance = new Singleton2();
        }
        return instance;
    }
}

测试代码:

  /**
     * 懒汉模式
     */
    @Test
    public void test01(){
        Singleton2 s1 = Singleton2.getInstance();
        Singleton2 s2 = Singleton2.getInstance();
        System.out.println(s1.hashCode());
        System.out.println(s2.hashCode());
    }

使用内部类的相关知识实现的单例模式:

package com.liwei.danli;

public class Singleton {
    private Singleton() {
    }

    private static class SingletonHolder {
        private final static Singleton INSTANCE = new Singleton();
    }

    public static Singleton getInstance() {
        return SingletonHolder.INSTANCE;
    }

    public static void main(String[] args) {
        Singleton instance1 = Singleton.getInstance();
        Singleton instance2 = Singleton.getInstance();
        System.out.println(instance1.hashCode());
        System.out.println(instance2.hashCode());
    }
}

上面的代码属于懒汉式单例,因为 Java 机制规定,内部类 SingletonHolder 只有在 getInstance() 方法第一次调用的时候才会被加载(这就是实现了实现了 lazy ),而且其加载过程是线程安全的。内部类加载的时候实例化一次 instance 。

下面的这篇文章介绍了单例模式的 7 种写法,涉及了有关线程方面知识的介绍。

单例模式的七种写法 - cantellow - ITeye技术网站
http://cantellow.iteye.com/blog/838473

原文地址:https://www.cnblogs.com/liweiwei1419/p/4380994.html