目录
1.前言:
spring默认管理的bean对象都是单例模式的,,除非根据scop注解更改作用域;
单例模型下,如果不设置全局私有变量时,不会出现多线程情况下,线程不安全问题;
每一个线程情况下的,单例对象的变量值、线程运行到哪一步都存在栈和程序计数器中,内存存储,没有线程不安全的情况;
如果类内设置公共变量,则要进行特殊处理,否则会出现多个线程共同引用一个局部变量,设计线程安全问题:
处理方式1:
使用threadLocal线程变量,进行处理
处理方式2:
使用Atomic原子类进行处理
2.单例对象的好处
节约系统资源,有时需要确保系统中某个类
只有唯一一个实例,当这个唯一实例创建成功之后,我们无法再创建一个同类型的其他对象,所有的操作都只能基于这个唯一实例。为了确保对象的唯一性,我们可以通过单例模式来实现,这就是单例模式的动机所在
3.如何手动设计一个单例对象类
3.1饿汉式单例类
项目初始加载时,进行自动创建
class BeanTest{
private static final BeanTest bean= new BeanTest();
private BeanTest() { }
public static BeanTest getBean() {
return bean;
}
}
3.2懒汉式单例类
和懒加载lazy类似的概念,第一次调用这个类的时候,在进行创建对象;
注意的就是,要做两次判断,以防多线程情况下,重复创建对象;
class LazyBean {
private volatile static LazyBean bean= null;
private LazyBean () { }
public static LazyBean getBean() {
//第一重判断
if (bean== null) {
//锁定代码块
synchronized (LazyBean.class) {
//第二重判断
if (bean == null) {
bean= new LazyBean (); //创建单例实例
}
}
}
return bean;
}
}
3.3IoDH单例类
懒汉和饿汉的合并优化,主要是借助创建一个内部静态类,代码如下
class IoDhBean{
private IoDhBean() {
}
private static class CreateBean{
private final static IoDhBean bean= new IoDhBean();
}
public static Singleton getBean() {
return CreateBean.bean;
}
//demo测试类是否一致
public static void main(String args[]) {
IoDhBean bean1 = IoDhBean.getBean();
IoDhBean bean2= IoDhBean.getBean();
System.out.println(bean1 ==bean2);
//J结果时true,没有重复创建对象
}
}
3.4借助spring
可以自定义一个类,借助spring注解,例如service、common等注解,吧这个类交给spring管理,
注意处理内部变量(根据业务规则进行处理)