参考博客:https://www.cnblogs.com/xudong-bupt/p/3433643.html
单例模式(Singleton)
这个模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在。在很多操作中,比如数据库连接都需要这样的单线程操作。这样做就是为了节省内存空间,保证我们所访问到的都是同一个对象。
单例模式要求保证唯一,那么怎么样才能保证唯一性呢?
1.私有化的构造函数,防止别人实例化这个对象
2.使用静态的方法获得对象;
3.有静态的属性,且这个属性是这个类的一个对象
public class Singleton {
//单例模式--线程
//1.多线程安全单例模式(不使用同步锁)
//直接初始化一个实例对象
/**
* 下列代码中的一个缺点是该类加载的时候就会直接new一个静态对象出来,当系统中这样的
* 类较多时,会使得启动速度变慢。现在流行的设计都是“延迟加载”,我们可以在第一次使用的时候
* 才开始初始化第一个该类对象。
* 这种适合小系统
*/
private static Singleton sin = new Singleton();
//private类型的构造函数,保证其他类对象不能直接new一个该对象的实例
private Singleton(){}
//该类唯一的public方法
public static Singleton getSin(){
return sin;
}
//2.多线程安全单例模式(使用同步方法)
/**
* 下述代码中的一次锁住了一个方法,这个粒度有点大,改进就是只锁住其中的new语句就可以。
* 就是所谓的"双重锁"机制
*/
//把声明的工作放到类的全局变量中完成,那么在下边就可以直接判断这个变量instance是否被实例化过了
private static Singleton instance;
//private类型的构造函数,保证其他类对象不能直接new一个该对象的实例
private Singleton(){}
//对获取实例的方法进行同步
public static synchronized Singleton getInstance(){
if(instance == null){
instance = new Singleton();
}
return instance;
}
//3.多线程安全单例模式(使用双重同步锁)
private static Singleton instance;
private Singleton(){}
//对获取实例的方法进行同步
public static Singleton getInstance(){
//先判断实例是否存在,不存在的话加锁
if(instance == null){
synchronized(Singleton.class){
/**
* 这里再次判断是为了解决:
* 当instance为null并且同时有两个线程调用getInstance()方法时,他们将都可以通过
* 第一重instance == null 判断。然后由于锁机制,这两个线程则只有一个进入,另一个
* 在外排队等候,必须要其中的一个进入并出来以后,另一个才能进入。而此时如果没有了
* 第二重的instance == null 判断,则第一个线程创建了实例,而第二个线程还是可以
* 继续再创建新的实例,就达不到单例的目的
*/
if(instance == null){
instance = new Singleton();
}
}
}
return instance;
}
}//Class