单例模式中的饿汉模式和懒汉模式

转自http://blog.sina.com.cn/s/blog_175b3022e0102x4ti.html

https://blog.csdn.net/abc19900828/article/details/39479377/

单例模式应用场合:对于某些对象只需要一个就够了的,比如旧社会的皇帝

现在我们来看一下懒汉模式与饿汉模式的实现代码
饿汉模式如下图:
JAVA设计模式(单例模式中的懒汉模式与饿汉模式详解)



在饿汉模式中,初始化变量的时候最好加上final关键字,这样更为严谨。
而懒汉模式则有以下两种:
1.不加锁
JAVA设计模式(单例模式中的懒汉模式与饿汉模式详解)



2.加锁
JAVA设计模式(单例模式中的懒汉模式与饿汉模式详解)


看完也许会奇怪,为何要加锁?一般来说大多数情况不加锁并没有任何问题,但是在多线程并发执行的时候就很容易出现安全隐患,第一个线程在判断newInstance==null时,还没有new出实例时,第二个线程也进来,判断的newInstance也是null,然后也会new出实例,这就不是我们想要的单例模式了,所以就需要加锁,使用synchronized关键字,加锁更能解决安全问题,但加锁同时也会出现一个问题,那就是每次都需要判断锁,这样性能就会降低,所以为了提高性能,我们应该尽量减少锁判断的次数,加上双重判断,也就是上图代码,个人推荐选择饿汉模式,直白点就是简单,安全。


总结比较:

饿汉式是线程安全的,在类创建的同时就已经创建好一个静态的对象供系统使用,以后不在改变。

懒汉式如果在创建实例对象时不加上synchronized则会导致对对象的访问不是线程安全的    

从实现方式来讲他们最大的区别就是懒汉式是延时加载,他是在需要的时候才创建对象,而饿汉式在虚拟机启动的时候就会创建,

饿汉式无需关注多线程问题、写法简单明了、能用则用。但是它是加载类时创建实例(上面有个朋友写错了)、所以如果是一个工厂模式、缓存了很多实例、那么就得考虑效率问题,因为这个类一加载则把所有实例不管用不用一块创建。懒汉式的优点是延时加载、缺点是应该用同步(想改进的话现在还是不可能,比如double-check)、其实也可以不用同步、看你的需求了,多创建一两个无引用的废对象其实也没什么大不了。

你可能感兴趣的:(java)