创建型模式-单例模式
创建型模式:
重点就是在如何创建对象,目的将对象创建和使用分离出来
单例模式:
首先用官方的话
介绍一下单例模式:
单例模式(Singleton),也叫单子模式,是一种常用的软件设计模式。在应用这个模式时,单例对象的类必须保证只有一个实例存在。许多时候整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为。比如在某个服务器程序中,该服务器的配置信息存放在一个文件中,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置信息。这种方式简化了在复杂环境下的配置管理
讲人话
1、一个单一的类,负责创建自己的类,目的就是确保系统中只有一个这样的类
2、单例特点:
– 构造方法私有化(不能随便new)
– 由类自己创建实例(自己编写一个方法【懒汉式/饿汉式】)
使用场景
1、什么场景用到?
多线程中的线程池
数据库的连接池
系统环境信息
上下文(ServletContext)
…
2、面试问题
系统环境信息(System.getProperties())?
Spring中怎么保持组件单例的?
ServletContext是什么(封装Servlet的信息)?是单例吗?怎么保证?
ApplicationContext是什么?是单例吗?怎么保证?
ApplicationContext: tomcat:一个应用(部署的一个war包)会有一个应用上下文
ApplicationContext: Spring:表示整个IOC容器(怎么保证单例的)。ioc容器中有很多组件(怎么保证单例)
数据库连接池一般怎么创建出来的,怎么保证单实例?
饿汉式:饿死鬼投胎,不管怎么样我先new了再说。
package com.xusj.future.singleton;
import lombok.Data;
/**
* 使用饿汉
* 不管三七二十一直接new
*
* @author xusj
* <br>CreateDate 2022/7/15 12:41
*/
@Data
public class Person {
private String name;
private int age;
/**
* 构造方法私有化
*/
private Person() {
}
private static Person instance = new Person();
public static Person getInstance() {
return instance;
}
}
懒汉式:比较懒,需要的时候才会去new,先是判断一下是否非空
考虑线程安全问题,考虑锁的粒度和效率
package com.xusj.future.singleton;
/**
* 使用懒汉式
* 当对象是空的时候才会创建对象,但是这个需要考虑线程安全问题
* <p>
* 锁的粒度等
*
* @author xusj
* <br>CreateDate 2022/7/15 12:50
*/
public class Dog {
private String name;
private int age;
/**
* 构造方法私有化,不能随便new
*/
private Dog() {
}
/**
* volatile内存可见性
*/
private volatile static Dog instance;
/**
* 线程安全分析:临界区存在共享变量的操作所以需要考虑线程安全
* <p>
* 第一种:方法加synchronized(锁粒度太大效率不高)
* 第二种:if外加对象锁,还是粒度太大
* 第三种:if内加对象锁,并检查一下这时的对象是否被创建(双重检查锁)
*/
public static Dog getInstance() {
if (instance == null) {
synchronized (Dog.class) {
// 双重检查
if (instance != null) {
instance = new Dog();
}
}
}
return instance;
}
}
测试类
package com.xusj.future.singleton;
/**
* @author xusj
* <br>CreateDate 2022/7/15 12:41
*/
public class SingletonTest {
public static void main(String[] args) {
// 使用饿汉式
Person instance = Person.getInstance();
Person instance1 = Person.getInstance();
System.out.println(instance.equals(instance1));
// 使用懒汉式
Dog dog1 = Dog.getInstance();
Dog dog2 = Dog.getInstance();
System.out.println(dog2==dog1);
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/96233.html