单例模式 singleton
可理解为:一个类只有一个实例. 单例模式相对来说比较简单,这里直接上代码直观感受一下。
实现
1.饿汉式
实现:
public class Singleton{
private static final Singleton INSTANCE = new Singleton();
private Singleton(){}
public static Singleton getInstance(){
return INSTANCE;
}
}
使用:
public class JustTaskMain(){
public static void main(String[] args){
Singleton s = Singleton.getInstance();
}
}
解释:
饿汉式写法,简单暴力,便于理解和编写
- 声明 private 无参构造方法,阻止外部实例化
- 声明唯一变量 INSTANCE 并实例化
- 提供静态方法访问获取 INSTANCE
这种写法的缺点在于,该单例类不管是否使用,在加载的时候就会进行实例化。 有点浪费资源,但是我们大多数情况并不 care 这种问题,所以这种简单易懂的写法也是推荐使用的。
2.懒汉式
实现:
public class Singleton{
private volatile static Singleton INSTANCE;
private Singleton(){}
public static Singleton getInstance(){
if(INSTANCE == null){
synchronized(this){
if(INSTANCE == null){
INSTANCE = new Singleton();
}
}
}
return INSTANCE;
}
}
使用:
public class JustTaskMain(){
public static void main(String[] args){
Singleton s = Singleton.getInstance();
}
}
解释:
不同于饿汉式,懒汉式是比较完美的一种写法,当然其实现起来会比较复杂,要考虑多线程的情况。
- volatile 声明唯一实例,避免即时编译器指令重排导致可能发生的返回空对象的情况,即地址不为空,但还未实例化完成,此时 INSTANCE == null 返回的是 true 。
- synchronized 加双重判空机制,避免多线程环境下实例化出两个实例
相比饿汉式的写法,懒汉式在使用到时才会进行实例化,资源创建后置,是比较完美的一种写法,但是实现时需要注意的点比较多,尤其要考虑到多线程的情况。
3.内部类
实现:
public class Singleton {
private Singleton() {
}
private static class InnerSingleton {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return InnerSingleton.INSTANCE;
}
}
使用:
public class JustTaskMain(){
public static void main(String[] args){
Singleton s = Singleton.getInstance();
}
}
这里继续拓展单例类的设计,使用内部类的方式也可以做到使用时加载,且 JVM 会帮我们保证线程安全。
- 声明 InnerSingleton 并在其中声明外部类实例并初始化,利用类加载特性,在加载过程中不会加载内部类,而通过外部方法获取实现了使用时加载。
4.枚举
实现:
public enum Singleton {
INSTANCE;
}
使用:
public class JustTaskMain(){
public static void main(String[] args){
Singleton s = Singleton.INSTANCE;
}
}
利用枚举特性可以简单而优雅的实现单例,如上。
其缺点大概就是,通常来说我们都是使用 class ,而使用 enum 来定义单例感觉上有些别扭。
总结
以上 4 种单例的实现方式,在工业级别的使用上都是没有问题的,在实际的选用中结合你工程的代码风格,选择最合适的即可。
其实在现在我们实际开发中大多数也不用自己定义单例了,基本都由框架实现好了,如 Spring 框架等。
希望本文对你有所帮助,同时 欢迎添加个人微信 dyinggq 一起交流学习~~
我是 dying 搁浅 ,我始终期待与你的相遇。无论你是否期待,潮涨潮落,我仅且就在这里…
我们下期再见~