
目录
如果说volatile不保证有序性,双重校验锁的写法是否有问题?
我们在设计多线程代码的时候,必须在满足线程安全的前提下,尽可能的提高任务执行的效率。使用多线程需要考虑的因素:
- 提高效率: 使用多线程就是为了充分利用CPU资源,提高任务的效率。
- 线程安全: 使用多线程最基本的就是保障线程安全问题。
单例模式是一种创建型设计模式,其目的是确保类只有一个实例,并且提供全局访问点以访问该实例。单例模式能保证某个类在程序中只存在唯一一份实例,而不会创建出多个实例。例如:DataSource(数据连接池),一个数据库只需要一个连接池对象。
在 Java 中,实现单例模式有多种方式,下面介绍其中的一些。
一、饿汉式单例
原理:基于类加载机制避免了多线程的同步问题。在饿汉式单例模式中,实例在类加载时就被创建,这种方式是满足线程安全的(JVM内部使用了加锁,即多个线程调用静态方法,只有一个线程竞争到锁并且完成创建,只执行一次),因此可以保证实例的唯一性。
具体来说,请看下面这个代码,
public class Single {
private static final Single INSTANCE = new Single();
private Single() {}
public static Single getInstance() {return INSTANCE;}
public static void main(String[] args) {
Single s1 = new Single().getInstance();
Single s2 = new Single().getInstance();
System.out.println(s1 == s2);
for(int i = 0; i < 100; i++){
new Thread(() ->
System.out.println(Singleton.getInstance().hashCode())
).start();
}
}
}
在这个例子中, INSTANCE 是一个静态常量,它在类加载时被初始化为 Single 类的实例。getInstance() 方法提供了对该实例的全局访问点。

优点:
- 写法比较简单,没有线程同步等复杂问题。
- 线程安全:实例在类装载的时候就完成实例化,避免了线程同步问题。
- 线程访问单例实例的速度比懒汉式单例模式更快。
缺点:
- 不是懒加载,如果从始至终从未使用过这个实例,会造成内存浪费。
- 如果类被不同的类加载器加载就会创建不同的实例。
- 如果单例类依赖于其他类,这些依赖的类在类加载时也会被创建。
二、懒汉式单例
原理:在懒汉式单例模式中,实例在第一次使用时才被创建。当实例没有被创建的时候,如果有多个线程都调用getInstance方法,就可能创建多个实例,就存在线程安全问题。但是实例一旦创建好,后面线程调用getInstance方法就不会出现线程安全问题。
- 私有化构造函数:防止外部通过new 关键字直接创建类的实例。
- 声明私有静态变量:用于存储类的唯一实例。
- 提供公共静态方法:首先检查实例是否已经创建,如果没有则创建实例并返回;如果已经创建则直接返回。
具体来说,请看下面这个代码,
public class Single {
private static Single instance;
//私有构造函数,防止外部实例化
private Single() {}
public static Single getInstance() {
if (instance == null) instance = new Single();
return instance;
}
public static void main(String[] args) {
Single s1 = new Single().getInstance();
Single s2 = new Single().getInstance();
System.out.println(s1 == s2);
for(int i = 0; i < 100; i++){
new Thread(() ->
System.out.println(Singleton.getInstance().hashCode())
).start();
}
}
}
在上面的实现中,instance 是静态变量,用于存储单例对象。在 getInstance 方法中,如果 instance 为 null,则创建一个新的 Singleton 对象,否则直接返回 instance。由于没有进行同步锁定,所以线程不安全,可能会导致并发创建多个实例的问题。

优点:
- 简单易懂,易于实现。
- 延迟加载:单例对象

最低0.47元/天 解锁文章
682

被折叠的 条评论
为什么被折叠?



