什么单例设计模式
单例设计模式:即某个类在整个系统中只能有一个实例对象可被获取或使用的代码模式
单例模式常见形式
1、饿汉式:直接创建对象,不存在线程安全问题
直接实例化饿汉式(简介直观)
枚举式(最简洁)
静态代码块饿汉式(适合复杂实例化)
2、懒汉式:延迟创建对象
线程不安全(适合于单线程)
线程安全(适合于多线程)
静态内部类形式(适用于多线程)
饿汉式
例1:直接创建实例对象
1 /** 2 * 饿汉式 3 * 直接创建实例对象,不管你是否需要这个对象 4 * 5 * (1) 构造器私有化 6 * (2) 自行创建,并且用静态变量保存 7 * (3) 向外提供这个实例 8 * (4) 强调这是一个单例,我们可以用final修饰 9 */ 10 public class Singleton01 { 11 12 public static Singleton01 instance = new Singleton01(); 13 14 private Singleton01 (){} 15 16 }
例2:枚举对象
1 /** 2 * 枚举类型:表示该类型的对象是有限的几个 3 * 可以限定一个,就成为单例了 4 */ 5 public enum Singleton02 { 6 7 INSTANCE; 8 9 }
例3:静态代码块形式
1 public class Singleton03 { 2 3 public static final Singleton03 INSTANCE; 4 5 private String info; 6 7 static { 8 try { 9 Properties properties = new Properties(); 10 properties.load(Singleton03.class.getClassLoader().getResourceAsStream("singleton.properties")); 11 12 INSTANCE = new Singleton03(properties.getProperty("info")); 13 }catch (IOException e) { 14 throw new RuntimeException(e); 15 } 16 17 } 18 19 private Singleton03 (String info){ 20 this.info = info; 21 } 22 23 public String getInfo() { 24 return info; 25 } 26 27 public void setInfo(String info) { 28 this.info = info; 29 } 30 }
懒汉式
例1:静态变量保存这个实例
1 /** 2 * 懒汉式: 3 * 延迟创建这个实例对象 4 * 5 * (1)构造器私有化 6 * (2)用一个静态变量保存这个实例 7 * (3)提供一个静态方法,获取这个实例对象 8 */ 9 public class Singleton04 { 10 private static Singleton04 instance; 11 12 private Singleton04(){} 13 14 public static Singleton04 getInstance() { 15 if(instance == null) { 16 try { 17 Thread.sleep(1000); 18 } catch (InterruptedException e) { 19 e.printStackTrace(); 20 } 21 instance = new Singleton04(); 22 } 23 return instance; 24 } 25 }
例2:静态方法线程安全
1 /** 2 * 懒汉式: 3 * 延迟创建这个实例对象 4 * 5 * (1)构造器私有化 6 * (2)用一个静态变量保存这个实例 7 * (3)提供一个静态方法,获取这个实例对象 8 */ 9 public class Singleton05 { 10 private static Singleton05 instance; 11 12 private Singleton05(){} 13 14 public static Singleton05 getInstance() { 15 synchronized (Singleton05.class) { 16 if(instance == null) { 17 try { 18 Thread.sleep(1000); 19 } catch (InterruptedException e) { 20 e.printStackTrace(); 21 } 22 instance = new Singleton05(); 23 } 24 } 25 26 return instance; 27 } 28 }
例3:内部类初始化
1 /** 2 * 在内部类被加载和初始化时,才创建INSTANCE实例对象 3 * 静态内部类不会自动随着外部类的加载和初始化而初始化,它是要独立去加载和初始化的 4 * 因为是在内部类加载和初始化时,创建的,因此是线程安全的 5 */ 6 public class Singleton06 { 7 8 private Singleton06(){} 9 10 private static class Inner{ 11 private static Singleton06 instance = new Singleton06(); 12 } 13 14 public Singleton06 getInstance(){ 15 return Inner.instance; 16 } 17 }