实现多线程有两种方式。 第一种是通过实现Runnable接口的run方法,并把Runnable实例传给父类Thread;
public class RunnableWay implements Runnable{
@Override
public void run() {
System.out.println("这是实现Runnable接口的方式");
}
public static void main(String[] args) {
Thread thread = new Thread(new RunnableWay());
thread.start();
}
}
第二是通过实现继承Thread,重写Thread的run方法。
public class ThreadWay extends Thread{
@Override
public void run() {
System.out.println("这是继承Thread父类的方式");
}
public static void main(String[] args) {
ThreadWay thread = new ThreadWay();
thread.start();
}
}
按照Java的类只能单继承缺陷,继承Thread类之后就不能继承其他类,最好是优先使用实现Runnable接口的方式最好。 源码解析 进入Thread的源码里面,找到线程执行的run方法,它对target参数进行非空判断,不为null 执行run方法
target参数就是Runnable接口
所以通过Runnable的方式,线程的执行过程是:先进入Thread的run方法里面进行非空判断(当然通过Runnable方式进来的,target自然不会为空),执行run方法;子类中重写了run方法,最终执行子类的run方法 -> 简单讲就是,会先走Thread源码,调用target.run()
而通过Thread方式的,子类会根据面对对象的继承定义,执行子类重写的方法,不会走源码。
1、同时执行传入Runnable和创建Thread会怎么样?
public class ThreadAndRunnable {
public static void main(String[] args) {
new Thread(new Runnable(){
@Override
public void run() {
System.out.println("这是传入Runnable实例的方式");
}
}){
@Override
public void run() {
System.out.println("这是Thread的方式");
}
}.start();
}
}
系统会输出 这是Thread的方式;
原因是:在匿名内部类中重写了run方法,而这个run方法是重写了Thread的run方法,源码的run方法重写了,Thread源码的run方法就没有生效了,就算传入Runnable,target不为空,run方法也不会执行了。
2、callable、线程池算创建线程的新方式吗?
先给出答案,并不是
ExecutorService executorService = Executors.newCachedThreadPool();
而源码中,也是通过Thread的方式创建的。
然后就是callable,直接上图(Tip:绿标的C是类,紫色的I是接口;实线是继承extends,虚线是实现implements),从图中我们可以看出,Callable也是跟Runnable方式创建线程有关,所以不算新的创建方式。
3、当前线程执行多次start方法会抛出异常吗?
答案:会抛出IllegalThreadStateException,start方法在刚执行的时候,会对当前线程状态进行检查
4、为什么不直接调用run方法?
调用start方法,它会经过线程的整个生命周期,而且start的底层也是会执行主线程的run方法;调用run方法,只是调用了一个普通方法,不会用子线程去调用。
谢谢观看,等待后续补充。。。。
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。