标签:sse ace jdk1.5 属性覆盖 缺点 反射机制 1.5 创建 调用
确保一个类只有一个实例,也就是类有且仅有一个对象,并且提供一个全局的访问点,外部通过这个访问点来访问该类的唯一实例
单例模式的写法有好几种,这里主要介绍四种:懒汉式单例、饿汉式单例、登记式单例、枚举式单例
不着急实例化,需要用的时候才初始化
public class Singleton {
private Singleton() {}
private static Singleton single=null;
public static Singleton getInstance() {
if (single == null) {
single = new Singleton();
}
return single;
}
}
缺点:
public class Singleton {
private Singleton() {}
private static Singleton singleton = null;
//为了保证多线程环境下正确访问,给方法加上同步锁synchronized
public static synchronized Singleton getInstance() {
if (singleton == null) {
singleton = new Singleton();
}
return singleton;
}
}
缺点:在方法调用上加了同步,虽然线程安全了,但是每次都有同步,会影响性能,毕竟99%是不需要同步的
public class Singleton {
private Singleton() {}
private static Singleton3 singleton3 = null;
//双重锁检查
public static Singleton getInstance() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton3();
}
}
}
return singleton;
}
}
优点:线程安全,且确保了只有第一次调用单例时才会做同步,避免了每次都同步的性能损耗;
缺点:双重锁降低了程序响应速度和性能
public class Singleton {
private Singleton() {}
//内部类的初始化需要依赖主类,需要先等主类实例化之后,内部类才能开始实例化
private static class LazyHolder {
//这里加final是为了防止内部将这个属性覆盖掉
private static final Singleton INSTANCE = new Singleton();
}
//这里加final是为了防止子类重写父类
public static final Singleton getInstance() {
return LazyHolder.INSTANCE;
}
}
优点:利用了classloader机制来保证初始化instance时只有一个线程,线程安全且没有性能损耗
类初始化的时候就立刻实例化,天生线程安全
public class Singleton {
private Singleton() {}
private static final Singleton singleton = new Singleton();
public static Singleton getInstance() {
return singleton;
}
}
缺点:多个消耗资源的单例同时实例化会影响系统的启动,如果后期这个单例没有被使用,会造成资源浪费
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* 注册登记式单例
* 类似Spring里面的方法,将类名注册,下次从里面直接获取
*/
public class Singleton {
//Spring最底层的这个容器就是一个map,说白了,IOC容器就是一个map
private static Map<String, Singleton> map = new ConcurrentHashMap<String, Singleton>();
//每个class对应一个map的key,也就是唯一的id
static {
Singleton singleton = new Singleton();
map.put(singleton.getClass().getName(), singleton);
}
//保护默认构造函数
protected Singleton() {}
//静态工厂方法,返回此类唯一的实例
public static Singleton getInstance(String name) {
if (name == null) {
name = Singleton.class.getName();
}
if (map.get(name) == null) {
try {
map.put(name, (Singleton) Class.forName(name).newInstance());
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
return map.get(name);
}
}
public enum Singleton {
INSTANCE;
public void getInstance() {
}
}
标签:sse ace jdk1.5 属性覆盖 缺点 反射机制 1.5 创建 调用
原文地址:https://www.cnblogs.com/wenzhihong/p/10600234.html