线程池
不要用executors创建线程,而是用threadpoolexecutor
OOM: OutOfMemoryError是因为使用了executors
public class Demo {
public static void main(String[] args) {
ExecutorService pool = new ThreadPoolExecutor(3,5,60, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(3), Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());
}
什么是工厂设计模式=new新建对象,它可以封装对象的创建细节,比如:为该对象进行加工和数据注入。 可以实现类与类之间的解耦操作
对象单例模式可以保证系统中一个类只有一个对象产生
饿汉式 为了达到目的:类一加载到内存,先加载静态成员,我们只需要new对象的时候将其变成static的就可以了
懒汉式:先不要new对象,什么时候使用,什么时候再new,但是还得保证只能是一个对象
问题:线程安全问题--new两次对象的情况 解决: 上锁
工厂设计--不直接new对象可以解耦最常用
public static Car createCar(String msg) {
switch (msg){
case "bmw":
Car car = new BmwCar();
car.setBrand("BMW750Li");
car.setColor("宝强绿");
car.setPrice(999999);
Car car = CarFactory.createCar("bmw");
car.run();
return car;
case "audi":
Car car2 = new AudiCar();
car2.setBrand("奥迪A8L");
car2.setColor("骚红");
car2.setPrice(888888);
Car car2 = CarFactory.createCar("audi");
car2.run();
return car2;
default:
return null;
}
}
}
什么是动态代理,就是用来对业务功能(方法)进行代理的
有了代理当访问某个方法时,会被代理对象拦截(拦截后可以对方法进行前增强、后增强【代理对象不会破坏原有方法的代码】)
支持任意接口类型(本身/被代理对象的所有方法)的实现类对象做代理
要求代理对象和被代理对象要实现相同的接口
代理对象 = Proxy.newProxyInstance(类加载器 , 父接口 , 处理器)
Proxy类是java中定义好的专门创建代理对象的类,该类需要一个"类加载器"
类加载器: 动态的加载.class文件
父接口 : 代理类和被代理类需要拥有共同的父接口
处理器: 代理对象拦截了方法后,对方法进行前增强、后增强,是由处理器来书写逻辑
代理对象 = Proxy.newProxyInstance(
类.class.getClassLoader(),
被代理类.class.getInterfaces(),
new InvocationHandler(){代理的核心处理逻辑
public Object invoke(
Object 代理对象,
Method 被拦截的方法对象 ,
Object[] 方法中的实参
){
}
}
)
List<String> list2 = Collections.unmodifiableList(list);
使用集合工具类获取不可变List集合报错-- ,现使用动态代理模拟获取不可变List集合
public class Demo05List {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
Collections.addAll(list,"Java","C++","Android","Python");
System.out.println(list);
List<String> list2 = proxyList(list);
System.out.println(list2);
System.out.println(list2.size());
System.out.println(list2.get(0));
System.out.println("--------------");
}
public static List<String> proxyList(List<String> list) {
ClassLoader classLoader = list.getClass().getClassLoader();
Class<?>[] interfaces = list.getClass().getInterfaces();
InvocationHandler invocationHandler = new InvocationHandler() {
参数一: Object proxy: 产生的代理对象,一般此处没用
参数二: Method method: 反射获取的方法对象,调用的代理对象的具体的方法
参数三: Object[] args: 调用的代理对象的具体的方法时,传递的参数列表
注意1: 使用代理对象调用任何方法,都会先执行invoke方法,
相当于具有拦截的功能,执行被代理对象的功能前可以执行其它功能,
在执行被代理对象的功能后可以执行其它功能
注意2: 调用代理对象的任何方法都会执行invoke方法进行拦截
invoke方法的返回值: Object类型: 被代理对象的方法的返回值
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String methodName = method.getName();
if ("dance".equals(methodName)) {
float money = (float) args[0];
if (money > 40000) {
return method.invoke(human,money/2);
}
} else if ("add".equals(methodName)) {
throw new UnsupportedOperationException("不支持添加操作");
} else if ("set".equals(methodName)) {
throw new UnsupportedOperationException("不支持修改操作");
}else if ("remove".equals(methodName)) {
throw new UnsupportedOperationException("不支持删除操作");
} else {
return method.invoke(list,args);
}
}
};
List<String> newList = (List<String>) Proxy.newProxyInstance(classLoader, interfaces, invocationHandler);
Human humanProxy = (Human) Proxy.newProxyInstance(classLoader, interfaces, invocationHandler);
humanProxy.dance(50000);
humanProxy.sing(30000);
humanProxy.eat();
return newList;
}
}
使用动态代理统计系统的每个方法执行的时间
public interface UserService {
String login(String loginName , String passWord) ;
void selectUsers();
boolean deleteUsers();
void updateUsers();
}
public class UserServiceImpl implements UserService{
@Override
public String login(String loginName, String passWord) {
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
if("admin".equals(loginName) && "1234".equals(passWord)) {
return "登录成功";
}
return "登录名和密码可能有毛病";
}
@Override
public void selectUsers() {
System.out.println("查询了100个用户数据!");
try {
Thread.sleep(2000);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public boolean deleteUsers() {
try {
System.out.println("删除100个用户数据!");
Thread.sleep(500);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
@Override
public void updateUsers() {
try {
System.out.println("修改100个用户数据!");
Thread.sleep(2500);
} catch (Exception e) {
e.printStackTrace();
}
}
}
## 创建代理对象的工具类
public class ProxyUtil {
public static <T> T getProxy(T obj) {
return (T)Proxy.newProxyInstance(obj.getClass().getClassLoader(),
obj.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
long startTimer = System .currentTimeMillis();
Object result = method.invoke(obj, args);
long endTimer = System.currentTimeMillis();
System.out.println(method.getName() + "方法耗时:" + (endTimer - startTimer) / 1000.0 + "s");
return result;
}
});
}
}
## 测试类
public class Test {
public static void main(String[] args) {
UserService userService = ProxyUtil.getProxy(new UserServiceImpl());
System.out.println(userService.login("admin", "1234"));
System.out.println(userService.deleteUsers());
userService.selectUsers();
userService.updateUsers();
}
}