单例(Singleton)设计模式
单例就是在程序的运行过程中,一个类只有一个实例的存在
饿汉式单例
线程安全的
public class Singleton {
//(1) 构造方法私有化
private Singleton() {};
//(2) 提供一个静态的私有的本类对象
//在Singleton类加载内存时给静态变量obj分配存储空间并初始化
private static Singleton obj = new Singleton();
//(3) 提供一个公共的方法返回这个类对象
public static Singleton getInstense() {
return obj;
}
}
线程不安全懒汉式单例
public class Singleton {
//(1) 构造方法私有化
private Singleton() {};
//(2) 提供一个静态的私有的本类对象,但不赋值
private static Singleton obj;
//(3) 提供一个公共的方法返回这个类对象
public static Singleton getInstense() {
//在第一次调用的时候对obj进行赋值
if (obj == null) {
obj = new Singleton();
}
return obj;
}
}
线程安全的懒汉式单例
给上述方法方法简单的加锁,便可使其变成线程安全的:
public class Singleton {
//(1) 构造方法私有化
private Singleton() {};
//(2) 提供一个静态的私有的本类对象,但不赋值
private static Singleton obj;
//(3) 提供一个公共的方法返回这个类对象
public synchronized static Singleton getInstense() {
//在第一次调用的时候对obj进行赋值
if (obj == null) {
obj = new Singleton();
}
return obj;
}
}
但是,多线程时,只在第一次访问并创建对象时,可能出现线程安全问题,而创建完之后,就没必要再使用锁了,故效率低下 解决思足路:将同步代码块的范围缩小
public class Singleton {
//(1) 构造方法私有化
private Singleton() {}
//(2) 提供一个静态的私有的本类对象,但不赋值
private static Singleton obj;
//(3) 提供一个公共的方法返回这个类对象
public static Singleton getInstense() {
//在第一次调用的时候对obj进行赋值
if (obj == null) {
synchronized (Singleton.class) {
if (obj == null) {
obj = new Singleton();
}
}
}
return obj;
}
}
应用场景
- 在应用场景中,某类只要求生成一个对象的时候,如一个班中的班长、每个人的身份证号等。
- 当对象需要被共享的场合。由于单例模式只允许创建一个对象,共享该对象可以节省内存,并加快对象访问速度。如 Web 中的配置对象、数据库的连接池等。
- 当某类需要频繁实例化,而创建的对象又频繁被销毁的时候,如多线程的线程池、网络连接池等。
视频讲解
[video(video-sIeGFmvC-1574932453067)(type-bilibili)(url-player.bilibili.com/player.html…)]