1.单例设计模式:所谓的单例设计模式,就是在整个软件系统当中,只会产生一个该类的对象。
2.实现方式有两种
2.1饿汉式
public class SingletonTest1 {
public static void main(String[] args) {
// Bank bank = new Bank();
Bank bank1 = Bank.getInstance();
Bank bank2 = Bank.getInstance();
// 检查是否相等,如果相等,则说明该类就一个实例
System.out.println(bank1 == bank2);
}
}
// 饿汉式实现单例设计模式:在调用之前就已经创建对象了
class Bank{
//1.私有构造器:意味着外部无法通过构造器去创建对象
private Bank(){
}
//2.类的内部去创建这个类的实例
private static Bank bank = new Bank();
//3.静态方法,返回其bank变量
public static Bank getInstance(){
return bank;
}
}
// 饿汉式的实现方式2
class Dog{
// 1.私有构造器
private Dog(){
}
// 2.静态变量接收静态代码块创建的对象
private static Dog dog = null;
// 3.静态代码块创建对象
static {
dog = new Dog();
}
// 4.静态方法返回dog变量
public static Dog getInstance(){
return dog;
}
}
2.2懒汉式(线程不安全)
package cn.xuguowen.java.singleton;
/*
* 单例设计模式之懒汉式实现方式:什么时候需要对象我就给你new对象
*/
public class SingletonTest2 {
public static void main(String[] args) {
Order order1 = Order.getInstance();
Order order2 = Order.getInstance();
System.out.println(order1);
System.out.println(order2);
System.out.println(order1 == order2);
}
}
// 懒汉式实现方式
class Order{
//1. 私有构造器
private Order(){
}
//2.声明属性,但没有初始化
private static Order order = null;
//3.静态方法返回其对象
public static Order getInstance(){
// 这样写方法体是错误的
// order = new Order();
// 因为这样每次调用方法就会new一次对象,然后将地址值赋值给order变量
if(order == null){
// 这样判断一下就解决了
order = new Order();
}
return order;
}
}
2.3解决懒汉式的线程安全问题
package cn.xuguowen.java2;
/**
* @author xuguowen
* @create 2021-02-20 9:21
* @Description 使用同步机制解决懒汉式单例设计模式中的线程安全问题
* 有两种方式
*/
public class SingletonTest {
}
class Bank{
// 私有构造器
private Bank(){
}
// 提供类变量
private static Bank instance = null;
// 提供方法,返回一个Bank对象
// 同步方法解决:效率稍差
/*public static synchronized Bank getInstance(){
if (instance == null) {
// 这样做存在线程安全问题:有可能多个线程都进入到if语句当中,那么就创建了多个实例对象
// 解决方式一:同步方法
instance = new Bank();
}
return instance;
}*/
public static Bank getInstance(){
// 方式一:使用同步代码块包裹:效率稍差
/*synchronized (Bank.class) {
if (instance == null) {
// 这样做存在线程安全问题:有可能多个线程都进入到if语句当中,那么就创建了多个实例对象
instance = new Bank();
}
return instance;
}*/
// 方式二:效率稍好
if (instance == null) {
// 这里虽然也会存在多个线程共同进入if语句,创建了实例之后,即使后面还会有线程进入,此时效率就高了
synchronized (Bank.class) {
if (instance == null) {
instance = new Bank();
}
}
}
return instance;
}
}
3.对比两种方式实现单例设计模式
- 饿汉式:对象加载时间过长,但是线程是安全的
- 懒汉式:延迟加载对象,线程不安全,需要解决。