单例模式Singleton
1.定义
保证一个类只有一个实例,并提供一个访问它(这个实例)的全局访问点。本质是控制实例数目。
1.1功能
保证这个类在运行期间只会被创建一个实例。
1.2单例的范围
如果一个虚拟机里有多个ClassLoader,且每个ClassLoader都装载一次Singleton,那么就可能会创建多个实例。如果有多个虚拟机且每个虚拟机都装载一次Singleton那么肯定就会创建多个实例了。
2.思路
通过一个类能够创建多个实例,根源在于它的构造方法是公开的,只要它的构造方法公开,类外就可以通过它构造多个实例。所以如果要控制实例的创建,就要控制构造方法的权限。
可以通过私有构造方法的形式收回权限。类里面提供一个公开方法返回实例(这个实例由这个类自己创建)
Singleton
private Singleton()
public Singleton getInstance()
懒汉模式
//第一次需要它的时候才创建一个实例,然后返回
//后面如果再次需要获取实例就要判断 /**有没有创建过**/
public class Singleton {
private static Singleton s=null;
private Singleton(){
//
}
//因为要判断是否创建过,所以要考虑多线程的问题
public static synchronized Singleton getInstance(){
if(s==null){
s=new Singleton();
}
return s;
}
//other methods and fields
}
---引出延迟加载思想
if (资源未加载){
//加载资源
}
一开始不加载资源,等到需要它的时候再加载,尽可能的节约资源
但是每次调用资源都要判断是不是已经加载过了
饿汉模式
//装载这个类的时候就已经创建了一个实例,以后需要获取实例直接把它返回就好了
public class Singleton {
private static Singleton s=new Singleton();
private Singleton(){
//
}
public static Singleton getInstance(){
return s;
}
//other methods and fields
}
--时间和空间和线程安全
懒汉模式是典型的时间换空间(每次都要判断是不是已经加载过资源,浪费了判断时间)
从线程安全来说 不加同步的懒汉线程也是不安全的,如果并发情况下多个线程访问了getInstance就可能会创建多个实例
懒汉--创建实例 怎么线程安全呢{
1.加同步但是这样会降低访问速度
2.双重加锁,资源volatile;先判断实例可存在,存在就返回;不存在再
synchronized(Singleton.class){
if(资源不存在){
//创建资源
}
}//这样就创建好资源后就不需要再同步了
也可以通过私有静态内部类里将资源静态化 的方式返回资源
//static 内部类的成员由jvm管理 保证只加载一次