------------单例总结--------------
1.什么是单例?
单例就是某个类在项目进行的生命周期中,永远只有一个实例
2.单例和单例模式的区别?
单例模式是实现单例的方法之一
(注意: spring中每个被管理bean默认是单例的,它是否使用了单例模式? 没有使用单例模式 )
<bean id="xxx" class="bean的全名称">.....
3.什么是单例模式?
如果满足以下3点的才是使用了单例模式
(1) 类本身的构造方法必须私有
(2)类本身提供一个自己的实例
(3)必须对外提供一个可以访问这个唯一实例的方法
4.单例模式的分类?
饿汉式 (没有线程安全问题)
public class SendURL {
//类本身提供一个自己的实例
private static SendURL instance =new SendURL();
//类本身的构造方法必须私有
private SendURL() {}
//必须对外提供一个可以访问这个唯一实例的方法
public static SendURL getInstance() {
return instance;
}
}
懒汉式 延迟加载(存在线程安全问题)
public class SendURL { //类本身提供一个自己的实例 private volatile static SendURL instance = null; //类本身的构造方法必须私有 private SendURL() {} //必须对外提供一个可以访问这个唯一实例的方法 public static SendURL getInstance() { if(instance == null){ //t1 t2 t3 在多个线程同时运行时,很有可能会产生多个实例对象 synchronized(SendURL.class) { if(instance == null) { instance =new SendURL(); } } } return instance; } }
5.单例模式的线程安全问题
(懒汉式有线程安全问题)
问题:在多个线程同时运行时,很有可能会产生多个实例对象,导致线程安全问题 ?
使用同步的方法解决这个问题,加上synchronized关键字
但是这样的写法线程还是不安全,因为两个线程可以同时进入if语句,线程A实例化对象返回之后,线程B不用经过判断能再实例化对象,并且返回另一个对象
所以又提出一种新的模式——Initialization on Demand Holder. 这种方法使用内部类来做到延迟加载对象,在初始化这个内部类的时候,
JLS(Java Language Sepcification)会保证这个类的线程安全