想不到吧,Java创建线程的方式只有一种

本文深入探讨Java创建线程的三种常见方式:继承Thread、实现Runnable接口和实现Callable接口。尽管表面上有三种,但实际上都通过Thread.start()启动,执行run()或call()方法。尽管start0()是native方法,但其底层操作系统层面的实现不在本文讨论范围。总结来说,Java API层面创建线程只有一种方式,即通过Thread类启动并执行任务。
摘要由CSDN通过智能技术生成

前言

看到这个标题的小伙伴先别着急喷我……在面试的时候,我们经常会被问到这种基础题:Java创建线程的方式有几种

比较正常的答法当然是三种:

  1. 继承Thread
  2. 实现Runnable接口
  3. 实现callable接口

一般来说这种属于送分题,不过大家都是这样答的,好像有点一般般,有没有什么答法能够让面试官眼前一亮呢?当然有!

事实上,这个问题可以从两个角度去思考:

  1. Java层次
  2. 操作系统层次

大部分人的回答都是从Java提供的API层次,所以得出了三种,甚至还有加上线程池四种的结论,但你有没有想过,Java本身是不具备在操作系统上创建线程能力的。

更深入点思考:

Java提供的API分别是怎么创建线程的?

继承Thread方式

第一种方式,在构造方法实际上只是做了一些状态的初始化, 并没有涉及线程的创建,关键点其实是在Thread类的start()方法:

public synchronized void start() {
        if (threadStatus != 0)
            throw new IllegalThreadStateException();
        group.add(this);
        boolean started = false;
        try {
            start0();
            started = true;
        } finally {
            try {
                if (!started) {
                    group.threadStartFailed(this);
                }
            } catch (Throwable ignore) {
            }
        }
    }

阅读这段代码,让你最有印象的肯定是这个start0方法,名字起得这么奇怪,可惜点进去会发现它是一个native方法,我们暂时先跟到这里。

实现Runnable接口

runnable是一个接口,代码十分简单:

@FunctionalInterface
public interface Runnable {
    /**
     * When an object implementing interface <code>Runnable</code> is used
     * to create a thread, starting the thread causes the object's
     * <code>run</code> method to be called in that separately executing
     * thread.
     * <p>
     * The general contract of the method <code>run</code> is that it may
     * take any action whatsoever.
     *
     * @see     java.lang.Thread#run()
     */
    public abstract void run();
}

思考下我们平时怎么用Runnable的?是不是实现这个接口,重写run方法,然后扔到Thread类里去执行?实际上我们继承Thread类也是要重写run方法,OK,我们再看看第三个。

实现callable接口

callable的情况好像有点不一样,它没有我们熟悉的run方法了:

@FunctionalInterface
public interface Callable<V> {

    V call() throws Exception;
}

然而真的没有吗?我们再来想想callable的用法,好像还有个FutureTask类没有出现,我们点进来就会发现,这个类居然是Runnable的实现类!

不用想了,直接看看run方法的逻辑,果然在这里有调用call()方法,那么是实际上我们还是可以认为是run方法的效果。

总结

从上面三个方式的分析,我们最终可以粗略得出来一个结论:

无论是继承Thread类还是实现接口,最终都是通过Thread类的start方法创建线程,由run方法执行逻辑

也就是说,对于Java提供的API来说,创建线程的方式实际上只有一种,也就是刚才得出来的结论。

到这里我们已经得到可以让面试官眼前一亮的答案了,那么这个native方法的具体逻辑是怎么实现的呢?这里我就不深入分析了,大家可以去找找相关博文,大概是创建线程后得到时间片时会由一个回调的处理来执行run方法的逻辑

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值