懒汉式单例
时间: 2023-08-13 14:07:29 浏览: 53
懒汉式单例是一种常用的单例设计模式,它的特点是在第一次调用获取实例的方法时才会创建实例,是一种延迟加载的方式。
下面是一个使用懒汉式单例实现的示例代码:
```java
public class Singleton {
private static Singleton instance;
private Singleton() {
// private constructor
}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
```
在上述代码中,私有的构造函数保证了该类不能被外部实例化,而静态的 `getInstance` 方法则用于获取该类的唯一实例。在第一次调用 `getInstance` 方法时,由于 `instance` 变量是 `null`,所以会创建一个新的实例并将其赋值给 `instance` 变量。之后再次调用 `getInstance` 方法时,因为 `instance` 变量已经被赋值,所以直接返回该实例即可。
需要注意的是,懒汉式单例虽然简单易用,但是并不是线程安全的。如果多个线程同时调用 `getInstance` 方法,可能会创建多个实例。为了解决这个问题,可以使用双重检查锁或者静态内部类等方式来确保线程安全。
相关问题
双重检查锁懒汉式单例
双重检查锁懒汉式单例是一种常见的单例实现方式,具体实现如下:
```java
public class Singleton {
private static volatile Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
```
在这个例子中,`getInstance()` 方法首先检查 `instance` 是否已经被实例化,如果没有,那么首先获取 `Singleton.class` 的锁,然后再次检查 `instance` 是否已经被实例化。如果没有,那么实例化 `instance`。使用 `volatile` 关键字可以保证多线程环境下的线程安全。
需要注意的是,双重检查锁懒汉式单例需要使用 `volatile` 关键字来确保多线程环境下的正确性。在 Java 5 之前,使用双重检查锁懒汉式单例可能会出现线程安全问题。在 Java 5 以后,JVM 对 `volatile` 关键字的实现进行了优化,可以确保多线程环境下的正确性。
懒汉式单例模式和饿汉式单例模式的异同
以下是懒汉式单例模式和饿汉式单例模式的异同:
相同点:
1. 都是单例模式,即保证一个类只有一个实例对象。
2. 都使用了私有的构造函数,防止外部创建实例对象。
3. 都使用了静态变量来保存实例对象。
不同点:
1. 创建对象的时机不同:饿汉式在类加载时就创建了对象实例,而懒汉式是在使用时才创建。
2. 线程安全性不同:饿汉式天生是线程安全的,因为在类加载时就已经创建了对象实例,而懒汉式需要考虑线程安全问题,可以使用synchronized关键字或者双重检查锁定等方式来保证线程安全。
3. 性能不同:饿汉式在类加载时就创建了对象实例,所以在访问速度和反应时间上都比懒汉式快,但是如果这个实例一直没有被使用,那么就会造成内存浪费。而懒汉式只有在使用时才会创建对象实例,所以在内存占用上比饿汉式要低,但是在访问速度和反应时间上会稍微慢一些。
下面是懒汉式单例模式的示例代码:
```python
class Singleton:
__instance = None
def __init__(self):
if Singleton.__instance != None:
raise Exception("该类已经实例化过了")
else:
Singleton.__instance = self
@staticmethod
def getInstance():
if Singleton.__instance == None:
Singleton()
return Singleton.__instance
```
下面是饿汉式单例模式的示例代码:
```python
class Singleton:
__instance = Singleton()
def __init__(self):
if Singleton.__instance != None:
raise Exception("该类已经实例化过了")
else:
Singleton.__instance = self
@staticmethod
def getInstance():
return Singleton.__instance
```