单例模式
一、介绍
确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例(定义一个私有访问权限的构造函数,避免被其他类new出来一个对象)。
优点:由于单例模式在内存中只有一个实例,减少了内存开支、可以避免对资源的多重占用、可以在系统设置全局的访问点;缺点:单例模式一般没有接口,扩展很困难。
public class Singleton {
private static final Singleton singleton = new Singleton();
//限制产生多个对象
private Singleton(){
}
//通过该方法获得实例对象
public static Singleton getSingleton(){
return singleton;
}
//类中其他方法,尽量是static
public static void doSomething(){
}
}
二、使用场景
1、在整个项目中需要一个共享访问点或共享数据。
2、创建一个对象需要消耗的资源过多。
3、需要定义大量的静态常量和静态方法。
三、注意事项
单例模式有几种不同的实现方式:
public class Singleton {
private static Singleton singleton = null;
//限制产生多个对象
private Singleton(){
}
//通过该方法获得实例对象
public static Singleton getSingleton(){
if(singleton == null){
singleton = new Singleton();
}
return singleton;
}
}
上述代码中当一个线程A执行到singleton = new Singleton(),但还没有获得对象(对象初始化是需要时间的),第二个线程
B也在执行,执行到(singleton == null)判断,那么线程B获得判断条件也是为真,于是继续运行下去,线程A获得了一个对象,线程B也获得了一个对象,在内存中就出现两个对象。
解决线程不安全的方法很有多,可以在getSingleton方法前加synchronized关键字,也可以在getSingleton方法内增加synchronized来实现。
在Java中,对象默认是不可以被复制的,若实现了
Cloneable接口,并实现了clone方法,则可以直接通过对象复制方式创建一个新对象,对象
复制是不用调用类的构造函数,因此即使是私有的构造函数,对象仍然可以被复制。