单例模式
单例(Singleton)模式的定义:指一个类只有一个实例,且该类能自行创建这个实例的一种模式。
单例模式的应用场景:
对于 Java 来说,单例模式可以保证在一个 JVM 中只存在单一实例。单例模式的应用场景主要有以下几个方面。
-需要频繁创建的一些类,使用单例可以降低系统的内存压力,减少 GC。
-某类只要求生成一个对象的时候,如一个班中的班长、每个人的身份证号等。
-某些类创建实例时占用资源较多,或实例化耗时较长,且经常使用。
-某类需要频繁实例化,而创建的对象又频繁被销毁的时候,如多线程的线程池、网络连接池等。
-频繁访问数据库或文件的对象。
-对于一些控制硬件级别的操作,或者从系统上来讲应当是单一控制逻辑的操作,如果有多个实例,则系统会完全乱套。
-当对象需要被共享的场合。由于单例模式只允许创建一个对象,共享该对象可以节省内存,并加快对象访问速度。如 Web 中的配置对象、数据库的连接池等。
/*
线程安全的懒汉式(双重检查加锁)
*/
public class LazySingleton {
//保证 instance 在所有线程中同步
private volatile static LazySingleton instance = null;
// 私有化构造方法,private 避免类在外部被实例化
private LazySingleton() {
}
public static LazySingleton getInstance() {
if (instance == null) {
synchronized (LazySingleton.class) {
if (instance == null) {
instance = new LazySingleton();
}
}
}
return instance;
}
}
/*
当getInstance方法第一次被调用的时候,它第一次读取SingletonHolder.instance,
导致SingletonHolder类得到初始化;而这个类在装载并被初始化的时候,会初始化它的静态域,从而创建Singleton的实例,
由于是静态的域,因此只会在虚拟机装载类的时候初始化一次,并由虚拟机来保证它的线程安全性
*/
public class HungrySingleton {
private static class SingletonHelper {
/**
* 静态初始化器,由JVM来保证线程安全
*/
private static HungrySingleton instance = new HungrySingleton();
}
private HungrySingleton(){
}
public static HungrySingleton getInstance(){
return SingletonHelper.instance;
}
public enum Singleton3 {
uniqueInstance;// 定义一个枚举的元素,它 就代表了Singleton的一个实例
添加自己需要的操作
public void singletonOperation() {
// 功能处理
System.out.println("功能处理");
}
}
代理模式
根据代理的创建时期,代理模式分为静态代理和动态代理。
静态:由程序员创建代理类或特定工具自动生成源代码再对其编译,在程序运行前代理类的 .class 文件就已经存在了。
动态:在程序运行时,运用反射机制动态创建而成
代理模式主要有两个目的:一是保护目标对象,二是增强目标对象。
要点:
JDK 实现代理只需要使用 newProxyInstance 方法,该方法需要接收三个参数,语法格式如下:
static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h )
注意该方法在 Proxy 类中是静态方法,且接收的三个参数说明依次为:
ClassLoader loader:指定当前目标对象使用类加载器,获取加载器的方法是固定的
Class<?>[] interfaces:目标对象实现的接口的类型,使用泛型方式确认类型
InvocationHandler h:事件处理,执行目标对象的方法时,会触发事件处理器的方法,把当前执行目标对象的方法作为参数传入
静态代理和动态代理的区别
1.静态代理只能通过手动完成代理操作,如果被代理类增加了新的方法,则代理类需要同步增加,违背开闭原则。
2.动态代理采用在运行时动态生成代码的方式,取消了对被代理类的扩展限制,遵循开闭原则。
3.若动态代理要对目标类的增强逻辑进行扩展,结合策略模式,只需要新增策略类便可完成,无需修改代理类的代码。