单例模式就是确保一个类只有一个实例,并提供全局访问点;主要被用于一个全局类的对象在多个地方被使用并且对象的状态是全局变化的场景。实现单例模式需要私有构造器、一个静态方法和一个静态变量。常见的单例模式有八种实现方式
饿汉式(静态常量)
在类中直接定义全局的静态对象的实例并初始化,然后提供一个方法获取该实例对象。在定义单例对象的同时将其实例化,直接可以使用,也就是说在Class Loader完成后该类的实例已经存在于JVM中了。
- 构造器私有化
- 类的内部创建对象
- 提供一个公有的静态方法,返回实例对象
public class Singleton {
private Singleton() {}
private final static Singleton instance = new Singleton();
public static Singleton getInstance() {
return instance;
}
}
优点:写法简单,在类装载的时候就完成实例化,避免了线程同步问题
缺点:在类装载的时候完成实例化,没有达到Lazy Loading的效果,如果从始至终都没有使用过这个实例,就造成内存的浪费
饿汉式(静态代码块)
public class Singleton {
private Singleton() {}
private static Singleton instance;
static {
instance = new Singleton();
}
public static Singleton getInstance() {
return instance;
}
}
优缺点与第一种写法一样
懒汉式(线程不安全)
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
起到了Lazy Loading的效果,但只能在单线程下使用,实际开发中,不推荐使用这种方式
懒汉式(线程安全,同步方法)
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
类中定义了单例但并没有实例化,实例化的过程是在获取单例对象的方法中实现的。
解决了线程安全问题,方法进行同步效率太低,在实际开发中,不推荐使用
懒汉式(线程安全,同步代码块)
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
instance = new Singleton();
}
}
return instance;
}
}
在实际开发中,不推荐使用
双重检查
public class Singleton {
private static volatile Singleton instance;
private Singleton() {}
public static synchronized Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
线程安全,可以延迟加载,效率较高;在实际开发中,推荐使用
静态内部类
public class Singleton {
private static volatile Singleton instance;
private Singleton() {
}
private static class SingletonInstance {
private static final Singleton INSTANCE = new Singleton();
}
public static synchronized Singleton getInstance() {
return SingletonInstance.INSTANCE;
}
}
采用类装载机制来保证初始化实例时只有一个线程;静态内部类方式在Singleton类被装载时并不会立即实例化,二是在需要实例化时,调用getInstance方法才会装载SingletonInstance类,从而完成Singleton的实例化。类的静态属性只会在第一次加载类的时候初始化,JVM保证了线程的安全性,在类进行初始化时,别的线程是无法进入的;实现了延迟加载,效率高,在实际开发中推荐使用
枚举
public enum Singleton {
INSTANCE;
}
使用枚举实现单例模式,避免了多线程同步问题,还能防止反序列化重新创建新的对象。Effective Java一书中推荐使用这种方式
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/76844.html