多线程
- 什么是多线程?
- 多线程好的讲解:
- 实现多线程
- 第一种:通过继承Thread类实现多线程
- 这种方式的缺点:
- 第二种:通过实现接口Runnable实现多线程
- 静态代理模式
- 什么是静态代理模式
- 动态代理模式
- 什么是动态代理模式:
- 和静态代理相比,动态代理的优势在哪
- 第三种
什么是多线程?
是一个提示执行多个线程的过程,用于多任务处理。
多线程好的讲解:
实现多线程
一共有三种方法
第一种:通过继承Thread类实现多线程
1. 继承Thread类
2. 重写run()方法
3. 通过start()方法启动线程
这种方式的缺点:
java的类是单继承的,一单继承了Thread类,就不允许去继承其它类
第二种:通过实现接口Runnable实现多线程
- 编写类实现Runnbale接口
- 实现run()方法
- 通过Thread类的start()方法启动线程
静态代理模式
什么是静态代理模式
若代理类在程序运行前就已经存在,那么这种代理方式被成为 静态代理 ,这种情况下的代理类通常都是我们在Java代码中定义的。
Thread --> 代理角色
MyRunnable --> 真实角色
代理角色与真实角色实现共同的接口Runnbale接口
举例:
You(你) -> 结婚 -> 真实角色
MarryCompary 代理角色
共同拥结婚的接口 ->结婚的方法
示例代码:
package com.DuoXianCheng.JinTaiDaiLi;
public interface Marry { //定义一个结婚的接口
void marry();
}
package com.DuoXianCheng.JinTaiDaiLi;
public class MarryCompany implements Marry{ //婚庆公司继承结婚这个业务
//婚庆公司给准备结婚的人准备婚礼
private Marry m; //将接口作为形参
public MarryCompany(Marry m){//通过构造方法进行赋值,将局部变量的值赋值给成员变量
this.m = m;
}
public void before(){
System.out.println("你结婚之前应该做的事");
}
@Override
public void marry() {
this.before();
m.marry(); //调用真实角色的结婚的方法
this.after();
}
public void after(){
System.out.println("你结婚之后应该做的事");
}
}
package com.DuoXianCheng.JinTaiDaiLi;
public class You implements Marry{ //真实角色
@Override
public void marry() {
System.out.println("你和XXX结婚");
}
}
package com.DuoXianCheng.JinTaiDaiLi;
public class Test { //测试类
public static void main(String[] args) {
//创建真实角色对象
Marry y = new You(); //接口new 实现类
//创建代理角色对象
Marry my = new MarryCompany(y);
my.marry();
}
}
运行结果:
动态代理模式
什么是动态代理模式:
代理类在程序运行时创建的代理方式被成为 动态代理
也就是说,这种情况下,代理类并不是在Java代码中定义的,而是在运行时根据我们在Java代码中的“指示”动态生成的。
和静态代理相比,动态代理的优势在哪
动态代理的优势在于可以很方便的对代理类的函数进行统一的处理,而不用修改每个代理类的函数。
参考代码:
首先创建一个接口,PersonDao
package com.DuoXianCheng.DongTaiDaiLi;
public interface PersonDemo { //定义一个人的基本接口
public void say();
}
然后写一个实现类PersonDaoImpl
package com.DuoXianCheng.DongTaiDaiLi;
public class PersonDaoImpl implements PersonDemo{ //实现类
@Override
public void say() {
System.out.println("time to eat");
}
}
然后写个使用类PersonHandler
PersonHandler必须要实现InvocationHandler接口
package com.DuoXianCheng.DongTaiDaiLi;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class PersonHandler implements InvocationHandler { //使用类
private Object obj; //这个就是要代理的真实对象
public PersonHandler(Object obj){
this.obj= obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before");
//当代理对象调用真实对象的方法时,它会自动跳转到代理对象关联的handler对象的invoke方法来进行调用
Object result = method.invoke(obj,args);
System.out.println("after");
return result;
}
}
写一个测试类
package com.DuoXianCheng.DongTaiDaiLi;
import java.lang.reflect.Proxy;
public class PersonTest {
public static void main(String[] args) {
PersonTest test = new PersonTest();
test.test();
}
public void test(){
PersonDemo pDao = new PersonDaoImpl();
PersonHandler handler = new PersonHandler(pDao);
/*
* 通过Proxy的newProxyInstance方法来创建我们的代理对象,我们来看看其三个参数
* 第一个参数pDao.getClass().getClassLoader() ,我们这里使用pDao这个类的ClassLoader对象来加载我们的代理对象
* pDao.getClass().getInterfaces(),我们这里为代理对象提供的接口是真实对象所实行的接口,表示我要代理的是该真实对象,这样我就能调用这组接口中的方法了
* 第三个参数 handler, 我们这里将这个代理对象关联到了上方的 PersonHandler 这个对象上
*/
PersonDemo proxy = (PersonDemo) Proxy.newProxyInstance(pDao.getClass().getClassLoader(), pDao.getClass().getInterfaces(),handler);
proxy.say();
}
}
运行结果:
有关动态代理模式代码的分析可以参考这个:
第三种
第三种方式是实现Callable接口,重写call方法
我们在另一篇文章内对这种方法进行分析