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