单例模式
一 懒汉模式
1 public class Singleton{ 2 private static Singleton singleton; 3 4 private Singleton() { 5 } 6 7 public synchronized static Single newInstance() { 8 if (singleton== null) { 9 singleton= new Singleton(); 10 } 11 return singleton; 12 } 13 }
懒汉模式在类加载的时候就实例化对象,这种模式缺点是不用这个对象的时候也会消耗内存,优点是线程安全。
二 饿汉模式
1 public class Singleton{ 2 private static Singleton instance = null; 3 private Singleton(){} 4 public static Singleton newInstance(){ 5 if(null == instance){ 6 instance = new Singleton(); 7 } 8 return instance; 9 } 10 }
饿汉模式在我们需要用这个对象再去实例化对象,缺点是线程不安全,有可能实例化了两个对象,优点是不实例化的时候不消耗内存。
以上两种单例都不是完美的单例,如果饿汉模式能线程安全就更完美了,线程安全自然想到加锁,但锁加的不好会非常消耗性能,如以下加锁方式就非常消耗性能:
1 public class Singleton{ 2 private static Singleton instance = null; 3 private Singleton(){} 4 public static synchronized Singleton newInstance(){ 5 if(null == instance){ 6 instance = new Singleton(); 7 } 8 return instance; 9 } 10 }
上面的代码虽然实现了线程安全,但是每次拿对象的时候都要排队,用的人多的时候就非常消耗性能了。
三 双重检查加锁
这个方式还是基于饿汉模式,如果我们能在创建对象的时候加锁,那么就完美的解决了性能的问题,并且线程也安全了。
1 public class Singleton { 2 private static Singleton instance = null; 3 private Singleton(){} 4 public static Singleton getInstance() { 5 if (instance == null) { 6 synchronized (Singleton.class) { 7 if (instance == null) { 8 instance = new Singleton(); 9 } 10 } 11 } 12 return instance; 13 } 14 }
四 静态内部类
1 public class Singleton{ 2 private static class SingletonHolder{ 3 public static Singleton instance = new Singleton(); 4 } 5 private Singleton(){} 6 public static Singleton newInstance(){ 7 return SingletonHolder.instance; 8 } 9 }
这种方式同样利用了类加载机制来保证只创建一个instance实例。它与饿汉模式一样,也是利用了类加载机制,因此不存在多线程并发的问题。不一样的是,它是在内部类里面去创建对象实例。这样的话,只要应用中不使用内部类,JVM就不会去加载这个单例类,也就不会创建单例对象,从而实现懒汉式的延迟加载。也就是说这种方式可以同时保证延迟加载和线程安全。

浙公网安备 33010602011771号