前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >并编之路《一》入门多线程的创建方式及常见误区

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

作者头像
呆呆
修改2021-10-09 10:09:38
2030
修改2021-10-09 10:09:38
举报
文章被收录于专栏:centosDai

一、线程创建方式

实现多线程有两种方式。 第一种是通过实现Runnable接口的run方法,并把Runnable实例传给父类Thread;

代码语言:javascript
复制
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方法。

代码语言:javascript
复制
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会怎么样?

代码语言:javascript
复制
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 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、线程创建方式
  • 二、两种方式的优先级
  • 面试题
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档