什么是单例模式?
单例设计模式是一种常用的软件设计模式,简单的来说,单例模式可以保证一个类只有一个实例并且该实例易于被外界访问.
为什么要使用单例模式?
举个例子:比如小张在银行中新开了个银行账号用于存钱,小张在在上海存了1000元, 然后小张由于出差,又在杭州存了1000元,小张只需要申请一个银行账号就行了,把两笔钱存在一个账号中就行了,所以现在小张的账户里面有2000元。在此案例中,申请的银行账户相当于一个实例,小张只需要创建一个银行账户,如果创建多个实例(相当于创建多个银行账号),则每张银行卡都有1000元。会使得对象重复,浪费内存资源。而且与实际不符,也会给用户带来误解,不知道哪一个才是真实的状态。
使用单例有什么好处?
首先能满足一些实际情况的需要,有利于节省内存,不需要创建多个对象。便于对象管理。
单例模式的要点:一是该类只能有一个实例;(该单例模式的类必须只提供私有的构造方法)
二是该类必须自行创建这个实例 (该类定义中含有一个该类的静态私有对象)
三是该类必须自行向整个系统提供这个实例。(该类提供了一个静态的共有的函数用于创建或获取它本身的静态私有对象)
单例模式的写法:饿汉式和懒汉式以及双重锁形式(多线程安全)
我们以Bank类为例子:
懒汉式:
public class Bank {
// 懒汉式单例
private static Bank bank; //私有化静态成员变量
private Bank() { //私有化构造方法
}
public static Bank getInstance() { //提供一个静态方法供外部调用
if (bank == null) {
bank = new Bank();
}
return bank;
}
}
饿汉式:
public class Bank1 {
// 饿汉式
// 静态属性在整个类加载时初始化,编译好的字节码文件时,静态属性只会被加载一次
private static Bank1 bank = new Bank1();
private Bank1() {
}
public static Bank1 getInstance() {
return bank;
}
}
双重锁模式:
此模式为了解决懒汉式当在多线程的情况下不能保证实例化的唯一性
这个模式将同步内容下方到if内部,提高了执行的效率,不必每次获取对象时都进行同步,只有第一次才同步,创建了以后就没必要了。
public class Bank2 {
private static Bank2 bank = null;
private Bank2() {
}
public static Bank2 getInstance() {
if (bank == null) {
synchronized (Bank2.class) {
if (null == bank) {
bank = new Bank2();
}
}
}
return bank;
}
}
测试代码类:
public class TextBank {
public static void main(String[] args) {
for (int i = 0; i <= 10; i++) {
Bank b = Bank.getInstance();
// 对象只有一个
System.out.println(b);
}
for (int i = 0; i < 10; i++) {
Bank1 bank1 = Bank1.getInstance();
System.out.println(bank1);
}
for (int i = 0; i < 10; i++) {
Bank2 bank2 = Bank2.getInstance();
System.out.println(bank2);
}
}
}
控制台输出如下:循环中指向的地址是同一个,所以说明只创建了一个实例。
com.bank.Singleton.Bank@2a139a55
com.bank.Singleton.Bank@2a139a55
com.bank.Singleton.Bank@2a139a55
com.bank.Singleton.Bank@2a139a55
com.bank.Singleton.Bank@2a139a55
com.bank.Singleton.Bank@2a139a55
com.bank.Singleton.Bank@2a139a55
com.bank.Singleton.Bank@2a139a55
com.bank.Singleton.Bank@2a139a55
com.bank.Singleton.Bank@2a139a55
com.bank.Singleton.Bank@2a139a55
com.bank.Singleton.Bank1@15db9742
com.bank.Singleton.Bank1@15db9742
com.bank.Singleton.Bank1@15db9742
com.bank.Singleton.Bank1@15db9742
com.bank.Singleton.Bank1@15db9742
com.bank.Singleton.Bank1@15db9742
com.bank.Singleton.Bank1@15db9742
com.bank.Singleton.Bank1@15db9742
com.bank.Singleton.Bank1@15db9742
com.bank.Singleton.Bank1@15db9742
com.bank.Singleton.Bank2@6d06d69c
com.bank.Singleton.Bank2@6d06d69c
com.bank.Singleton.Bank2@6d06d69c
com.bank.Singleton.Bank2@6d06d69c
com.bank.Singleton.Bank2@6d06d69c
com.bank.Singleton.Bank2@6d06d69c
com.bank.Singleton.Bank2@6d06d69c
com.bank.Singleton.Bank2@6d06d69c
com.bank.Singleton.Bank2@6d06d69c
com.bank.Singleton.Bank2@6d06d69c