什么是单例模式
- 单例模式:是指在内存中只会创建且仅创建一次对象的设计模式。在程序中多次使用同一个对象且作用相同时,为了防止频繁地创建对象使得内存飙升,单例模式可以让程序仅在内存中创建一个对象,让所有需要调用的地方都共享这一单例对象。
单例模式的类型
单例模式有两种类型:
- 懒汉式:在真正需要使用对象时才去创建该单例类对象
- 饿汉式:在类加载时已经创建好该单例对象,等待被程序使用
饿汉式
package single;
public class Hungry {
//构造器私有
private Hungry(){
}
//创建对象
private static Hungry hungry=new Hungry();
//创建方法
private static Hungry getInstance(){
// 返回对象
return hungry;
}
}
懒汉式
public class LazyMan {
//构造器私有
private LazyMan(){
}
// 懒汉式先判断是要执行方法,执行在创建对象
private static LazyMan lazyMan;
private static LazyMan getInstance(){
if (lazyMan==null){
lazyMan=new LazyMan();
}
return lazyMan;
}
}
但在多条线程执行下就会出现问题
package single;
public class LazyMan {
//构造器私有
private LazyMan(){
System.out.println(Thread.currentThread().getName()+"-->");
}
// 懒汉式先判断是要执行方法,执行在创建对象
private static LazyMan lazyMan;
public static LazyMan getInstance(){
if (lazyMan==null){
lazyMan=new LazyMan();
}
return lazyMan;
}
public static void main(String[] args) {
for (int i = 0; i <10 ; i++) {
new Thread(
()->{
LazyMan.getInstance();
}
).start();
}
}
}
会有多个线程进入,所以我们就要加锁
也就出现了DCL懒汉式
package single;
public class LazyMan {
//构造器私有
private LazyMan() {
System.out.println(Thread.currentThread().getName() + "-->");
}
// 懒汉式先判断是要执行方法,执行在创建对象
private static LazyMan lazyMan;
public static LazyMan getInstance() {
// 加锁当lzayMan==null时加锁,这是就称为双重检测锁模式(简称DCL懒汉式)
if (lazyMan == null) {
synchronized (LazyMan.class) {
if (lazyMan == null) {
lazyMan = new LazyMan();
}
}
}
return lazyMan;
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new Thread(
() -> {
LazyMan.getInstance();
}
).start();
}
}
}
注意:
但是加锁之后,还会问题就是利用反射破解单例模式
这是就需要用到枚举了