1、单例模式介绍
单例模式是为了在系统使用过程中,同一个对象之创建一次,后续不断的重复使用,实现方式:1、静态变量(即时加载、延迟加载);2、静态内部类即时加载
2、单例模式几种实现方式
-
1、单线程/多线程操作(类加载创建)
/** * [@Author](https://my.oschina.net/arthor) liufu * @CreateTime 2017/8/15 15:08 */ public class SingleThreadObject { //类装载就构建了本对象,通过静态属性永久指向这个对象地址,从而达到单例效果 private static SingleThreadObject instance = new SingleThreadObject(); public static SingleThreadObject getInstance(){ return instance; } //假设在另一个类中使用它(为了方便,写在了同一个类) public static void main(String[] args) { SingleThreadObject obj1 = SingleThreadObject.getInstance(); SingleThreadObject obj2 = SingleThreadObject.getInstance(); System.out.println(obj1 == obj2); System.out.println(obj1.hashCode() == obj2.hashCode()); } }
效果截图
-
2、单线程/多线程操作(延迟创建,加锁)
由于需要传递参数,对象久不能够在类加载的时候构建,而是需要在线程用到的时候,传递参数进来,比如
/** * [@Author](https://my.oschina.net/arthor) liufu * @CreateTime 2017/8/15 15:08 */ public class SameThreadObject { private Properties param; //这个构造方法最好设置为private,这样外面无法new,只能够通过getInstance来创建 private SameThreadObject(Properties param){ this.param = param; } //类装载就构建了本对象,通过静态属性永久指向这个对象地址,从而达到单例效果 //由于需要传递参数,只能延迟创建,而且多线程加锁,只能够由一个线程来构建 private static SameThreadObject instance; //多线程,加锁,双重判断 public static SameThreadObject getInstance(Properties param){ if (instance == null){ synchronized ("getInstance"){ if (instance == null){ instance = new SameThreadObject(param); } } } return instance; } //假设在另一个类中使用它(为了方便,写在了同一个类) public static void main(String[] args) { Properties param = new Properties(); SameThreadObject obj1 = SameThreadObject.getInstance(param); SameThreadObject obj2 = SameThreadObject.getInstance(param); System.out.println(obj1 == obj2); System.out.println(obj1.hashCode() == obj2.hashCode()); } }
-
3、单线程/多线程操作(内部静态类)
静态内部类延迟创建,类加载器天生对多线程友好,兼顾延迟加载和多线程问题
问题是:没法传递参数,因为一旦调用这个类,他就创建了这个对象
import java.util.Properties; /** * [@Author](https://my.oschina.net/arthor) liufu * @CreateTime 2017/8/15 15:08 */ public class DelyCreateInnerObject { //假设在另一个类中使用它(为了方便,写在了同一个类) public static void main(String[] args) { Properties param = new Properties(); DelyCreateInnerObject obj1 = DelyCreateInnerObject.getInstance(); DelyCreateInnerObject obj2 = DelyCreateInnerObject.getInstance(); System.out.println(obj1 == obj2); System.out.println(obj1.hashCode() == obj2.hashCode()); } /** * 即实现了延迟创建,也实现了多线程下锁带来的性能消耗 * 这两个是绝佳组合 * @return */ private static DelyCreateInnerObject getInstance(){ return DelyCreateInnerObjectNest.instance; } static class DelyCreateInnerObjectNest{ private static DelyCreateInnerObject instance = new DelyCreateInnerObject(); } }