保证内存中只有一个实例
1,不能被new? ==> 私有构造方法 或者 abstract 类(不能生成对象实例)
2,不能被new,那如何产生自己的示例给调用者? ==> static方法
3,如果是并发的第一次被调用,那又怎样处理? ==> 同步锁
懒汉模式写法
以上写法比较累赘把
饿汉模式写法
public class StarveSingleton { private static StarveSingleton s=new StarveSingleton(); private StarveSingleton(){} public static StarveSingleton getInstance(){ return s; } }
这种写法比较脱俗一点,没有用到同步锁,那么有人问,为什么不用静态块初始化呢?如果使用静态块初始化,静态块中不能抛异常Exception,只能抛错误Error,但是一旦有异常,类没法初始化,直接就是一个错误
饿汉式是线程安全的,在类被加载的同时就已经创建好一个静态的对象供系统使用,以后不再改变。
优点是无需关注多线程问题、写法简单明了、能用则用,
但如果类很大,譬如:需要同步的业务方法很复杂、很多,需要缓存很多其它对象,那么就得考虑效率问题,因为这个类一加载则把所有实例不管用不用一块创建。
单从资源利用效率角度来讲,这个比懒汉式稍差些。
从速度和反应时间角度来讲,则比懒汉式稍好些。
懒汉式是延时加载,是在需要的时候才创建对象。
优点是延时加载、缺点是应该用同步(想改进的话现在还是不可能,比如Double-Check)。
如果在创建实例对象时不加上synchronized则会导致对对象的访问不是线程安全的,譬如 并发访问getInstance,判断都是null,new出2个实例。
最好用双锁,不要把同步加在方法上,非常影响性能
其实也可以不用同步、看你的需求了,多创建一两个无引用的废对象其实也没什么大不了。
而且,延时加载也延时不到哪里,因为,类被加载到虚拟机,不就是要继续调用getInstance嘛