并编之路《一》入门多线程的创建方式及常见误区

一、线程创建方式

实现多线程有两种方式。
第一种是通过实现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方法
runMethod
target参数就是Runnable接口

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的方式创建的。

Executors

然后就是callable,直接上图(Tip:绿标的C是类,紫色的I是接口;实线是继承extends,虚线是实现implements),从图中我们可以看出,Callable也是跟Runnable方式创建线程有关,所以不算新的创建方式。
callable
3、当前线程执行多次start方法会抛出异常吗?

答案:会抛出IllegalThreadStateException,start方法在刚执行的时候,会对当前线程状态进行检查
threadStatus
Exception
4、为什么不直接调用run方法?

调用start方法,它会经过线程的整个生命周期,而且start的底层也是会执行主线程的run方法;调用run方法,只是调用了一个普通方法,不会用子线程去调用。

谢谢观看,等待后续补充。。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值