独一无二的对象
有什么用?
有很多对象我们只需要一个:
eg:线程池、缓存、注册表、日志对象等。
这些类我们只需要一个,如果制造出多个实例,会导致许多问题的产生。
eg:程序的行为异常、资源使用过量、结果不一致
下面是单件模式的代码:
public class SingleMode{
// 私有化静态该类属性
private static SingleMode instance;
// 私有化构造方法
private SingleMode() {
instance = new SingleMode();
}
// 提供一个公共获取该类实例的静态方法
public static SingleMode getInstance() {
if(instance==null) {
instance = new SingleMode();
}
return instance;
}
}
这是最经典的延迟实例化的单例模式写法,我们可以在使用的时候才创建。可是这个写法不适合多
线程,如果多个线程同时第一次调用获取该类实例的方法,可能会创建两个实例对象
我们可以通过给获取该实例的静态方法加上(synchronized)关键字
// 提供一个公共获取该类实例的方法
public static synchronized SingleMode getInstance() {
if(instance==null) {
instance = new SingleMode();
}
return instance;
}
这种方法虽然可以解决多线程问题,但是我们只需要在第一次调用次方法的时候,才需要同步。
但 是我们设置了synchronized关键字以后,我们每次调用这个方法都需要同步,成了一种累赘
,会降低我们的运行效率。
我们可以依赖JVM在加载这个类的时候马上创建此唯一的实例,代码如下:
public class SingleMode{
private static SingleMode instance = new SingleMode();
private SingleMode() {
}
public static synchronized SingleMode getInstance() {
return instance;
}
}
还可以利用双重检查来完善单例模式,如果没有创建该对象,我们就进行同步,也就是说,只有第一次才会进行同步:
public class SingleMode{
// 私有化静态该类属性
// volatile 确保instance被初始化WieSingleMode实例的时候,多个线程可以正确的处理instance变量
private volatile static SingleMode instance;
// 私有化构造方法
private SingleMode() {
instance = new SingleMode();
}
// 提供一个公共获取该类实例的方法
public static SingleMode getInstance() {
if(instance==null) {
synchronized(SingleMode.class) {
if(instance == null) {
instance = new SingleMode();
}
}
}
return instance;
}
}