模式定义
确保一个类最多只有一个实例,并提供一个全局访问点。
单例模式分为饿汉式和懒汉式。
懒汉式单例模式:在类加载时不初始化。
饿汉式单例模式:在类加载时就完成了初始化,所以类加载比较慢,但获取对象的速度快。
饿汉式-线程安全
/** * 饿汉式单例模式(线程安全) */ public class Singleton { //static单例变量 private static Singleton singleton = new Singleton(); //私有的构造方法 private Singleton() { } //静态方法为调用者提供单例对象 public static Singleton getInstance() { return singleton; } }
懒汉式-线程不安全
/** * 懒汉式(线程不安全) */ public class Singleton2 { private static Singleton2 instance = null; private Singleton2() { } public static Singleton2 getInstance() { if (instance == null) { instance = new Singleton2(); } return instance; } }
懒汉式-线程安全
/** * 懒汉式(线程安全) */ public class Singleton3 { private static Singleton3 instance = null; private Singleton3() { } public static synchronized Singleton3 getInstance() { if (instance == null) { instance = new Singleton3(); } return instance; } }
双重校验锁-线程安全
/** * 双重校验锁(线程安全) */ public class Singleton4 { private volatile static Singleton4 instance = null; private Singleton4() { } /** * 当第一次调用getInstance()方法时,instance为空,同步操作,保证多线程实例唯一 * 当第一次后调用getInstance()方法时,instance不为空,不进入同步代码块,减少了不必要的同步 */ public static Singleton4 getInstance() { if (instance == null) { synchronized (Singleton4.class) { if (instance == null) { instance = new Singleton4(); } } } return instance; } }
静态内部类-线程安全
/** * 静态内部类(线程安全) */ public class Singleton5 { /** * 静态内部类 */ private static class SingleHolder { public static Singleton5 instance = new Singleton5(); } //第一次调用getInstance方法时,才会去加载SingleHolder类,继而实例化instance public static Singleton5 getInstance() { return SingleHolder.instance; } private Singleton5() { } }
静态代码块-线程安全
/** * 静态代码块(线程安全) */ public class Singleton6 { private Singleton6() { } private static Singleton6 instance = null; // 静态代码块 static { instance = new Singleton6(); } public static Singleton6 getInstance() { return instance; } }
枚举-线程安全
/** * 枚举(线程安全) */ public enum Singleton7 { //枚举实例的创建是线程安全的,任何情况下都是单例(包括反序列化) INSTANCE; }
测试各种单例模式的线程安全
package com.wpx.singleton; public class SingletonDemo implements Runnable { public static void main(String[] args) { SingletonDemo[] threads = new SingletonDemo[10]; for (int i = 0; i < threads.length; i++) { threads[i] = new SingletonDemo(); } for (int i = 0; i < threads.length; i++) { new Thread(threads[i]).start(); } } @Override public void run() { // System.out.println(Singleton.getInstance().hashCode());//饿汉式单例模式(线程安全) // System.out.println(Singleton2.getInstance().hashCode());//懒汉式(线程不安全) // System.out.println(Singleton3.getInstance().hashCode());//懒汉式(线程安全) // System.out.println(Singleton4.getInstance().hashCode());//双重校验锁(线程安全) // System.out.println(Singleton5.getInstance().hashCode());//静态内部类(线程安全) // System.out.println(Singleton6.getInstance().hashCode());//静态代码块(线程安全) System.out.println(Singleton7.INSTANCE.hashCode());//枚举(线程安全) } }
java.lang.Runtime中的单例模式(饿汉式-线程安全)
public class Runtime { private static Runtime currentRuntime = new Runtime(); public static Runtime getRuntime() { return currentRuntime; } private Runtime() { } }