一 . 自定义一个类 extends Thread 类
1.在我们自己的类中重写run方法 ,run方法就是线程体即线程要执行的动作
2.创建我们自己的类的一个实例,new Class() 调用Thread类中的start()方法 。
3.start()方法会自动调用run()方法,线程启动
二 . 自定义类 implements Runnable 接口
1.在我们自己的类中重写run方法 ,run方法就是线程体即线程要执行的动作
2.创建我们自己类的一个实例对象,Class A=new Class() , 然后以该实例对象作为构造Thread类的实例对象的参数。即 Thread tr=new Thread(A);
3.调用 Thread 类中的start方法,start()方法会自动调用run()方法,线程启动
三 . 两种方法的关联
1. 静态代理模式: 举个生活情景,结婚人 与 婚庆公司 之间 ,两者都必须实现共同的接口,婚庆公司持有结婚人的引用 。
如:
interface marry{
public abstract void marry();
}
class marryPeople implements marry{
public void marry(){}
}
class marryCompany implements marry{
marryPeople mp;
marryCompany( marryPeople mp){
this.mp=mp;
} //在构造器中,将真实角色的引用传给代理人
public void marry(){
mp.marry();
} //在代理人的marry方法中实际是以真实角色调用其自身的marry()方法
public void before(){}
//婚庆公司结婚前的准备
public void after(){}
//婚庆公司之后的安排;
}
2. 回归正题 ,两种不同的方式 之间的关联;
实现Runnable 接口的方法 ,本质上采用的也是静态代理模式,先创建该类(实现了Runnable类的这个类)的实例对象 r ,再创建Thread类的实例对象(使用带参构造器),之后调用start()方法时 ,如果r!=null ,实际调用的还是 r 中的run 方法。
在这里,附上start方法的JDK 源码:
private native void start0();
/**
* If this thread was constructed using a separate
* <code>Runnable</code> run object, then that
* <code>Runnable</code> object's <code>run</code> method is called;
* otherwise, this method does nothing and returns.
* <p>
* Subclasses of <code>Thread</code> should override this method.
*
* @see #start()
* @see #stop()
* @see #Thread(ThreadGroup, Runnable, String)
*/
@Override
public void run() {
if (target != null) {
target.run();
}
}
另外, 还有一种方式 JDK5引入的callable接口 ,用来实现多线程
在这里暂时作为了解 ,callable能够声明异常,并且能有返回值
总结:
1.两个方法的底层实现都是调用了Thread类中的start方法 ,然后start方法调用run方法
2.第一个方法只是单继承,有局限性
3.第二个方法采用多实现 ,解决了单继承的弊端!