java基础---单例编写:单例工具的创建:数据库连接
=====================================================================
========双重检测
public class Singleton{
private volatile static Singleton instance;
private Singleton(){}
public Singleton getInstance(){
if(instance==null){
synchronized(Singleton.class){
if(instance==null)instance=new Singleton();
}
}
return instance;
}
}
---先判断是否instance被创建,如果被创建直接返回实例的引用。
---第二次判断的原因是,当ab线程同时判断instance==null并且等待获取锁的时候,a线程先获取锁并创建了实例,b线程又获取锁同时认为instance是空的,回再次创建,所以要进行第二次判断。
---使用volatile修饰的原因是使用volatile防止指令重排序。因为调用构造函数新建对象和将对象地址赋值给instance的顺序可能被重排序过。在new Singleton()之前会先分配内存空间并且有默认值,这个时候如果重排序将地址传给instance,那么一个新的线程进来发现instance!=null就会直接return这个时候会出问题,因为这个时候instance只是默认值还没有new出对象。
=======静态内部类
public class Singleton{
private static class SingletonHolder{
public static final Singleton INSTANCE = new Singleton();//单例所以final修饰
}
private Singleton(){}//内部类调用一次,所以构造函数对外就不能够调用了
public static Singleton getSingleton(){
return SingletonHolder.INSTANCE;
}
}
---会实现延迟加载,因为当应用不使用内部类,JVM就不会去加载单例类,也就不会去创建单例对象。