高性能的线程安全单例——Java基础语法系列

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/shuai_wy/article/details/84300806

大家都知道,一般实现单例有两种写法: 饿汉式 和 懒汉式, 饿汉式是线程安全的,在编译期间已完成初始化,加载到了内存里。 懒汉式一般写法是非线程安全的, 那懒汉式的线程安全单例应该如何实现呢,以及如何写出低耗能的线程安全单例呢 ?

单例实现关键点

  • 构造函数私有,private
  • 实例对象 静态 且 私有
  • 公开获取实例的静态方法

下面我们直接上代码了,按重要程度排序,提供三种方式:

一、高性能的线程安全单例 - 懒汉式

关键注意点:

  • volatile 关键字修饰实例对象, 禁止指令重排序
  • 加锁实例初始化过程
  • 判断实例对象为空时,进行双重校验
package safe;

/**
 * @description 线程安全的单例——懒汉式加载
 * @author [email protected]
 * @date 2018/11/20
 */
public class LazySingleton {
    /**
     * volatile 修饰属性,简直指令重排序
     */
    private static volatile LazySingleton lazySingleton = null;

    private LazySingleton() {
        //模拟: 创建线程为耗时操作
        try {
            Thread.sleep(1000L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static LazySingleton getInstance()  {
    	// 双重校验
        if (null == lazySingleton) {
            synchronized(LazySingleton.class) {
                if (lazySingleton == null) {
                    lazySingleton = new LazySingleton();
                }
            }
        }
        return lazySingleton;
    }

    public static void main(String args[]) {
        for (int i = 0; i < 10; i ++) {
            new Thread(() -> {
                System.out.println(LazySingleton.getInstance());
            }).start();
        }
    }
}

二、线程安全单例 - 懒汉式

同样是懒汉式,但是这次实现的方式不一样,我们直接选择在 获取实例的方法上,加上同步锁, 但是缺点就是有点消耗性能。

package safe;

/**
 * @description 线程安全的单例-懒汉-消耗性能
 * 将 Sychronized 关键字加载方法上,消耗性能
 * @author [email protected]
 * @date 2018/11/20
 */
public class LazySingleton_SyncMethod {
    private LazySingleton_SyncMethod() {}
    private static LazySingleton_SyncMethod instance = null;
    public static synchronized LazySingleton_SyncMethod getInstance() {
        if (instance == null) {
            instance = new LazySingleton_SyncMethod();
        }
        return  instance;
    }

    public static void main(String args[]) {
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                System.out.println(LazySingleton_SyncMethod.getInstance());
            }).start();
        }
    }
}

三、线程安全单例-饿汉式

编译期间,直接完成了初始化。

package safe;

/**
 *
 * @description  饿汉单例
 * @author [email protected]
 * @date 2018/11/20
 */
public class HungerSingleton {
    private static HungerSingleton ourInstance = new HungerSingleton();

    public static HungerSingleton getInstance() {
        return ourInstance;
    }

    private HungerSingleton() {
    }

    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Thread(() -> {
                System.out.println(HungerSingleton.getInstance());
            }).start();
        }
    }
}

猜你喜欢

转载自blog.csdn.net/shuai_wy/article/details/84300806
今日推荐