单例模式详解
理解
保证一个类仅有一个实例,并提供一个访问它的全局访问点。为了节省系统资源的时候,并且这个只需要一个实例。所以:
- 单例类只能有一个实例。
- 单例类必须自己创建自己的唯一实例。
- 单例类必须给所有其他对象提供这一实例。
我的单例类
饿汉式(一开始就创建所需要的实例)
public class MySingletonObject {
private static MySingletonObject instance = new MySingletonObject();
private MySingletonObject() {
}
//提供获取实例的方法
public static MySingletonObject getInstance(){
return instance;
}
}
懒汉式(需要实例时再创建)
public class MySingletonObject1 {
private static MySingletonObject1 instance;
public MySingletonObject1() {
}
//提供获取实例的方法
public static MySingletonObject1 getInstance() {
if (instance == null) {
//保证对线程环境下能正常使用
synchronized (MySingletonObject1.class) {
//在判断是因为在前一个判空判断在多线程环境中可能会有多个先后进入同步块,后进入的不需要再次实例
if(instance == null){
instance = new MySingletonObject1();
}
}
}
return instance;
}
}
测试主启动类
public static void main(String[] args) {
MySingletonObject instance1 = MySingletonObject.getInstance();
MySingletonObject instance2 = MySingletonObject.getInstance();
//判断饿汉式单例类创建的实例是否是相同的
System.out.println(instance1 == instance2);//out -> true
MySingletonObject1 instance3 = MySingletonObject1.getInstance();
MySingletonObject1 instance4 = MySingletonObject1.getInstance();
//判断懒汉式单例类创建的实例是否是相同的
System.out.println(instance3 == instance4);//out -> true
}
使用场景
该类全局只有需要实例一个对象时,例如:
- 一些设备管理器常常设计为单例模式,比如一个电脑有两台打印机,在输出的时候就要处理不能两台打印机打印同一个文件。
- Java是单进程的,所以,在一个JVM中,Runtime类的实例只有一个。
- WEB 中的计数器,不用每次刷新都在数据库里加一次,用单例先缓存起来。
优点:
- 在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例(比如管理学院首页页面缓存)。
- 避免对资源的多重占用(比如写文件操作)。
缺点:
- 没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。