一 说明
只能生成一个实例的类就是实现了Singleton(单例)模式的类型。
二 四种实现方式
1 最简单的写法(单线程)
这种写法只适用于单线程环境,上代码:
public class Singleton {
private static Singleton instance= null;
// 构造函数为private,阻断通过new Singleton1()的方式新建实例
private Singleton() {
}
// 每次获取实例的时候通过调用此类方法
public static Singleton Instance() {
if(instance == null) {
instance = new Singleton();
}
return instance;
}
}
缺点:只适用于单线程,当有二个线程同时运行到if(instance == null) 语句时,instance还为null,此时,二个线程都会执行 instance = new Singleton1(),改进方案见2
2 利用锁,可使用于多线程
public class Singleton {
private static Singleton instance = null;
private static Lock lock = new ReentrantLock();
private Singleton() {
}
public static Singleton instance() {
lock.lock();
if(instance == null) {
instance = new Singleton();
}
lock.unlock();
return instance;
}
}
通过锁的使用,保证了线程安全。缺点就是加锁开销大,优化见3
3 减少锁开销的优化版
public class Singleton {
private static Singleton instance = null;
private static Lock lock = new ReentrantLock();
private Singleton() {
}
public static Singleton instance() {
// 加锁前做一个判断,减少开销
if(instance == null) {
lock.lock();
if(instance == null) {
instance = new Singleton();
}
lock.unlock();
}
return instance;
}
}
4 利用静态构造函数
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton() {
}
public static Singleton instance() {
return instance;
}
}
代码相对简化了很多,唯一的缺点 instance并不是第一次用到Singleton的时候,就会被创建,而是第一次用到Singleton的时候,就会被创建。假设我们给Singleton再增加一个静态方法,调用该静态方法,不需要创建实例instance,但按照目前这种情况,仍然会过早地创建实例,从而降低内存的使用效率。