java饿汉式,懒汉式(面试专用,适合新人)

今天我们来说说单例模式;

1,什么是单例模式

通俗来讲,只被实例化一次。
官方回答,保证一个jvm中只有一个实例(不是在多个jvm之中。)

2,为什么使用单例模式(单例模式的好处)

  1. 在单例模式中,活动的单例只有一个实例,对单例类的所有实例化得到的都是相同的一个实例。这样就 防止其它对象对自己的实例化,确保所有的对象都访问一个实例
  2. 单例模式具有一定的伸缩性,类自己来控制实例化进程,类就在改变实例化进程上有相应的伸缩性。
  3. 提供了对唯一实例的受控访问。
  4. 由于在系统内存中只存在一个对象,因此可以 节约系统资源,当 需要频繁创建和销毁的对象时单例模式无疑可以提高系统的性能。
  5. 允许可变数目的实例。
  6. 避免对共享资源的多重占用。

3, 单例的缺点

  1. 不适用于变化的对象,如果同一类型的对象总是要在不同的用例场景发生变化,单例就会引起数据的错误,不能保存彼此的状态。
  2. 由于单利模式中没有抽象层,因此单例类的扩展有很大的困难。
  3. 单例类的职责过重,在一定程度上违背了“单一职责原则”。
  4. 滥用单例将带来一些负面问题,如为了节省资源将数据库连接池对象设计为的单例类,可能会导致共享连接池对象的程序过多而出现连接池溢出;如果实例化的对象长时间不被利用,系统会认为是垃圾而被回收,这将导致对象状态的丢失。

4,单例的注意事项

  1. 使用时不能用反射模式创建单例,否则会实例化一个新的对象
  2. 使用懒单例模式时注意线程安全问题
  3. 饿单例模式和懒单例模式构造方法都是私有的,因而是不能被继承的,有些单例模式可以被继承(如登记式模式)

5, 单例的应用场景

单例模式只允许创建一个对象,因此节省内存,加快对象访问速度,因此对象需要被公用的场合适合使用,如多个模块使用同一个数据源连接对象等等。如:

  1. 需要频繁实例化然后销毁的对象。
  2. 创建对象时耗时过多或者耗资源过多,但又经常用到的对象。
  3. 有状态的工具类对象。
  4. 频繁访问数据库或文件的对象。

6, 经典的单例模式—饿汉式

package controller;
/**
 * 
* 项目名称:shejimoshi  
* 类描述:("饿汉式")
* 创建人:莫参商 
* 创建时间:2020-1-8 下午4:34:27  
* 修改人:acer     
* @version   
*   
 */

class SingletonTest01{
	
	private static final SingletonTest01 singletonTest = new SingletonTest01();
	
	private SingletonTest01(){}
	
	public static SingletonTest01 getSingletonTest(){
		
		return singletonTest;
	}
	
}
public class Singleton01 {
	
	public static void main(String[] args) {
		SingletonTest01 s1 = SingletonTest01.getSingletonTest();
		SingletonTest01 s2 = SingletonTest01.getSingletonTest();
		System.out.println(s1==s2);
		
	}

}

饿汉式优点:

1, .class文件被加载的时,就会被初始化,天生线程安全; 2, 在类加载的同时已经创建好一个静态对象,调用时反应速度快

缺点:

资源效率不高,可能getInstance()永远不会执行到,但执行该类的其他静态方法或者加载了该类(class.forName),那么这个实例仍然初始化

7, 懒汉式

package controller;


/**
 * 
* 项目名称:shejimoshi  
* 类描述:("单例模式,懒汉式")
* 创建人:莫参商 
* 创建时间:2020-1-8 下午4:17:20  
* 修改人:acer     
* @version   
*   
 */
class SingletonTest{
	private static SingletonTest singletonTest;
	private SingletonTest(){
	}
	public static SingletonTest getSingletonTest()
		if (singletonTest==null) {
			//线程安全,同步代码块
			synchronized (SingletonTest.class) {
				singletonTest = new SingletonTest();
			}
		 }
		return singletonTest;
	}
}
public class Singleton {
	public static void main(String[] args) {
		SingletonTest s1 = SingletonTest.getSingletonTest();
		SingletonTest s2 = SingletonTest.getSingletonTest();
		System.out.println(s1==s2);
	}
}

优点:

当使用的时候才初始化,然后一直就是一个,不占用资源。

缺点

线程相比饿汉式不安全一些,并且因为加了同步代码块等原因,执行效率要比饿汉式慢一些。

总结

我们正常工作中,使用最多的就是懒汉式,它虽然有很多问题,但是各方面,性价比是最高的。

发布了7 篇原创文章 · 获赞 7 · 访问量 209

猜你喜欢

转载自blog.csdn.net/qq_41566219/article/details/103894377