剑指offer第二题:单例模式
1 package ren.laughing.jianzhi; 2 3 /** 4 * 饿汉式:在类创建的同时就已经创建好一个静态的对象供系统使用,以后不再改变,所以天生是线程安全的。 5 * 6 * @author Laughing_Lz 7 * @time 2016年5月16日 8 */ 9 public class Singleton1 { 10 private static final Singleton1 singleton1 = new Singleton1();// 饿汉式,static直接创建实例,节省时间但是会一直占用内存,天生线程安全 11 // 私有构造函数 12 13 private Singleton1() { 14 15 } 16 17 public Singleton1 getSingleton() { 18 return singleton1; 19 } 20 }
1 package ren.laughing.jianzhi; 2 /** 3 * 懒汉式:在第一次调用的时候实例化自己 4 * 但是线程不安全 5 * @author Laughing_Lz 6 * @time 2016年5月16日 7 */ 8 public class Singleton2 { 9 private static Singleton2 singleton2 = null; 10 //私有构造函数 11 private Singleton2(){ 12 13 } 14 public Singleton2 getSingleton(){ 15 if(singleton2 == null){ 16 singleton2 = new Singleton2(); 17 } 18 return singleton2; 19 } 20 21 }
1 package ren.laughing.jianzhi; 2 /** 3 * 懒汉式-修改1:在方法调用上加了同步,虽然线程安全了,但是每次都要同步,会影响性能。 4 * @author Laughing_Lz 5 * @time 2016年5月16日 6 */ 7 public class Singleton3 { 8 private static Singleton3 singleton3 = null; 9 //私有构造器 10 private Singleton3() { 11 12 } 13 public static synchronized Singleton3 getSingleton(){//synchronized 同步 防止多个线程同时访问这个方法, static 对这个类的所有对象实例起作用 14 if(singleton3 == null){ 15 singleton3 = new Singleton3(); 16 } 17 return singleton3; 18 } 19 }
1 package ren.laughing.jianzhi; 2 /** 3 * 懒汉式-修改2:双重检查锁定 4 * 在getSingleton中做了两次null检查,确保了只有第一次调用单例的时候才会做同步,这样也是线程安全的,同时避免了每次都同步的性能损耗 5 * @author Laughing_Lz 6 * @time 2016年5月16日 7 */ 8 public class Singleton4 { 9 private static Singleton4 singleton4 = null; 10 //私有构造器 11 private Singleton4(){ 12 13 } 14 public static Singleton4 getSingleton(){ 15 if(singleton4 == null){ 16 synchronized (Singleton4.class) {//双检锁:只有第一次调用单例时候才会同步 (Singleton4.class 锁定的一定要是类吗? singleton4实例行不行) 17 if(singleton4 ==null){ 18 singleton4 = new Singleton4(); 19 } 20 } 21 } 22 return singleton4; 23 } 24 }
1 package ren.laughing.jianzhi; 2 3 /** 4 * 静态内部类:按需创建实例★ 5 * Singleton4虽然通过双检锁避免了同步的性能损耗 6 * 但是有可能会过早的创建实例(比如调用Singleton4中存在的静态方法,并不需要实例),降低内存的使用效率 7 * 而在这里则可以实现 按需创建实例 8 * @author Laughing_Lz 9 * @time 2016年5月16日 10 */ 11 public class Singleton5 { 12 // 私有构造器 13 private Singleton5() { 14 15 } 16 17 public static Singleton5 getSingleton() { 18 return LazyGet.SINGLETON5;// 调用内部类来获取单例 19 } 20 //静态内部类 21 private static class LazyGet { 22 private static final Singleton5 SINGLETON5 = new Singleton5(); 23 } 24 }