实战Java高并发程序设计——单例模式

时间:2021-05-18 23:49:48

   单例模式是设计模式中使用最为普遍的模式之一。它是一种对象创建模式,用于产生一个对象的具体实例,它可以确保系统中一个类只有一个实例。这种模式有一下两个好处:

1.对于使用频繁地对象,可以省略new操作花费的时间。特别是对于那些重量级对象而言,能够节省很多系统开销。

2.由于new操作的频率减少,系统内存的使用频率也会降低。这将减少JVM的GC压力。

   下面来看一种单例实现

public class Singleton1{
private Singletion1{}
private static Singleton1 instance = new Singleton1();
public static Singleton getInstance(){
return instance;
}
}

   创建单列模式需要注意一下几点:

  1. 我们要把Singleton类的构造函数设置成private,这是为了防止开发人员用过构造函数随意创建这个类的实例。

  2. nstance则必须是private static的,private是为了防止instance被修改,保证其安全性;static是因为getInstance()方法是static的。

   使用以上这种实现模式能够保证该类是单例的,但是这种实现方式有一个不足,那就是instance实例的创健时间是不受控制的。


   如果想要精确控制instance的创健时间,我们可以使用中延迟加载策略,具体实现方式如下:

public class Singleton2{
private Singleton2(){}
private static Singleton2 instance = null;
public static synchronized Singleton2 getInstance(){
if (instance == null)
instance = new Singleton2();
return instance;
}
}

   使用这种策略就能将instance的实例化推迟到第一次使用Singleton2的时候。注意在getInstance方法上,我们加了synchronized关键字,只是为了防止在多线程下instance被多次创健。因此这种方法的缺点也就暴露出来了,那就是在竞争激烈的场合,其性能肯定会受到影响


   以上两种方法各有好坏,那有没有结合上述两种方法优势的第三中方法呢?答案肯定是有的。

public class Singleton3{
private Singleton3{
System.out.println("Singleton3 is created");
}
private static class SingletonHolder{//定义一个静态内部类来初始化Singleton
private static Singleton3 instance = new Singleton3();
}
public static Singleton3 getInstance(){
return SingletonHolder.instance;
}
}

   这种方法有以下2个好处:

  1. getInstance()方法没有加锁,在高并发环境下具有高性能。

  2. 只有在getInstance()第一次调用的时候,才会实例化instance。这是因为这里巧妙地使用了静态内部类和类的初始化方式。