廊坊人才网:当阿里面试官问我:Java建立线程有几种方式?我就知道问题没那么简朴

时间:5个月前   阅读:28

‘这是最新的大厂面试系列’, 还原真实场景[,提炼出知识点分享给人人。
点赞再看,养成习惯~ ‘微’信搜索【(武哥聊编程)】,关注这个 Java 菜鸟。

昨天有个小伙伴[去阿内里试实习生岗位,‘‘面试官’问他了一个老生常谈’的问题:你说一说 Java 『建立线程都有哪些 “「<方式>」”[』?

「这哥们心中」窃喜, 这个[老生常谈的问题早已背的滚瓜烂熟,“于是很流利的说了出来”。

Java 建立线程有两种 “「<方式>」”[:

  1. 继续Thread〖类〗,〖并重写〗run() “「<方式>」”[
  2. ‘实现’Runnable《 (接口)[》,笼罩《 (接口)[》中的run() “「<方式>」”[,并把Runnable《 (接口)[》的‘实现’扔给Thread

‘面试官’:(“拿出一张白纸”)那你把这两种 “「<方式>」”[写一下『吧』!

{小哥}:((这)有何难!)【好】~

public static void main(String[] args) {
	// 第一种
    MyThread myThread = new MyThread();
    myThread.start();
	// 第二种
    new Thread(() -> System.out.println("自己‘实现’的run-2")).start();
}

public static class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println("自己‘实现’的run-1");
    }
}

‘面试官’:【嗯】,那除了这两种,另有其他建立线程的 “「<方式>」”[吗?

这些简朴的问题难不倒这哥们,于是他想到了 Java5 <之后的>ExecutorsExecutors〖工具〗〖类〗<可以>用来建立线程池。

{小哥}:Executors〖工具〗〖类〗是用来建立线程池的,《这个》线程池<可以>指定线程个数,也<可以>不指定,(也<可以>指定定时器的线程池),它有如下常用的 “「<方式>」”[:

newFixedThreadPool(int nThreads):建立牢固数目的线程池
newCachedThreadPool():建立缓存线程池
newSingleThreadExecutor():建立单个线程
newScheduledThreadPool(int corePoolSize):“建立定时器线程池”

‘面试官’:【嗯】,OK,<咱们照样针对你刚刚>写的代码,“ 我再问你个问题[”。

“此时这”哥们有种不祥的预感,是不是自己代码写的有点问题?‘或者要问我底层‘实现’’?

‘面试官’:你写的两种建立线程的 “「<方式>」”[,都涉及到了run() “「<方式>」”[,“你【领会过】”Thread‘里的’run() “「<方式>」”[详细是怎么‘实现’的吗?

果真问到了源码了,《这哥们之前看了点》,<以是不是很慌>,回忆了一下, 向‘面试官’道来[。

{小哥}:emm……Thread 中的run() “「<方式>」”[里器械很少,{就一个} if 判断:

@Override
public void run() {
	if (target != null) {
		target.run();
	}
}

有个target〖工具〗,会去判断该变量是否为空,非空的时刻,去执行target〖工具〗中的run() “「<方式>」”[,(否则啥也不)干。而这个target〖工具〗,〖就是我们说的〗Runnable

/* What will be run. */
private Runnable target;

‘面试官’:【嗯】, 那这个[Runnable〖类〗“你【领会过】”吗?
{小哥}:【领会过】,这个Runnable「〖类〗很」简朴,{就一个}抽象 “「<方式>」”[:

@FunctionalInterface
public interface Runnable {
    public abstract void run();
}

这个抽象 “「<方式>」”[也是run()!若是我们使用Runnable《 (接口)[》,“就需要‘实现’这个”run() “「<方式>」”[。【由于这个】Runnable〖类〗上面标了@FunctionalInterface〖注解〗,以是<可以>使用函数式编程。

那{小哥}接着说:(突然自信起来了)以是这就对应了适才说的两种建立线程的 “「<方式>」”[,如果我用第一种 “「<方式>」”[: 〖继续了〗[Thread〖类〗,然后重写了run() “「<方式>」”[,那么它就不会去执行上面这个默认的run() “「<方式>」”[了(即不会去判断target),会执行我重写的run() “「<方式>」”[逻辑。

如果我是用的第二种 “「<方式>」”[:‘实现’Runnable《 (接口)[》的 “「<方式>」”[,那么它会执行默认的run() “「<方式>」”[,然后判断target“不为空”,再去执行我在Runnable《 (接口)[》中‘实现’的run() “「<方式>」”[。

‘面试官’:OK,<可以>,“ 我再问你个问题[”。

{小哥}:(暗自窃喜)

‘面试官’:那若是我既 〖继续了〗[Thread〖类〗,同时我又‘实现’了Runnable《 (接口)[》,【好】比这样,“最后会打印什么”信息出来呢?

‘面试官’边说边拿起刚刚这{小哥}写的代码,(对它进行了)简朴的修改:

public static void main(String[] args) {
    new Thread(() -> System.out.println("runnable run")) {
        @Override
        public void run() {
            System.out.println("Thread run");
        }
    }.start();
}

这{小哥},突然有点懵,【似乎从来没想过这个问题】,一时没有什么思绪,于是回覆了个:会打印 “Thread run” 『吧』……

‘面试官’:《谜底是对》的,然则为什么呢?

这{小哥}一时没想到缘故原由,于是‘面试官’让他回去<可以>思索思索,就继续下一个问题了。

亲爱的读者同伙,你们知道为什么吗?你们<可以>先思索一下。

实在这个谜底很简朴,〖我们来剖析一下代码便知〗:【实在是】 new 了一个〖工具〗(【子〖工具〗】) 〖继续了〗[Thread〖工具〗(父〖工具〗),在【子〖工具〗】里重写了父〖类〗的run() “「<方式>」”[;然后父〖工具〗内里扔了个Runnable进去,父〖工具〗中的run() “「<方式>」”[就是最初谁人带有 if 判断的run() “「<方式>」”[。

【好】了,现在执行start()后,一定先在子〖类〗中找run() “「<方式>」”[,找到了,父〖类〗的run() “「<方式>」”[自然就被干掉了,以是会打印出:Thread run。

若是我们现在假设子〖类〗中没有重写run() “「<方式>」”[,那么一定要去父〖类〗找run() “「<方式>」”[,父〖类〗的run() “「<方式>」”[中就得判断是否有Runnable〖传进来〗,现在有一个,以是执行Runnable中的run() “「<方式>」”[,那么就会打印:Runnable run 出来。

说白了,就是问了个 Java (语言自己的父子继续关系),会优先执行子〖类〗重写的 “「<方式>」”[而已,《只是借这个场景》,换了个提问的 “「<方式>」”[,‘面试者可能一时没反应过’来,有点懵也是正常的,若是直接问,傻子都能回覆的出来。

后记:通过这道简朴的面试题,帮人人剖析了一下在建立线程过程中的源码,<可以>看出来,面试过程中,‘面试官’加倍看重一些原理性的器械,而不是背一下 “「<方式>」”[就行了。「同时也能看的出」,面试大厂,需要做【好】充实的准备。另外,在面试的时刻要镇定,可能有些问题并没有太难,回覆不出来只是那时太紧张造成的。

“这篇文章就写到这”,最后祝人人都能面试乐成。

若是以为有辅助,希望老铁们来个三连击,给更多的人看到这篇文章

1、关注我的原创‘微’信民众号「(武哥聊编程)」,专注于Java、 数据结构和算法[、‘微’“服务”、中间件等手艺分享,(保证你看完有所)收获。

2、给俺点个赞呗,<可以>让更多的人看到这篇文章,顺便激励下我继续写作,〖嘻嘻〗。

,

Sunbet

Sunbet www.sunbet.xyz是Sunbet(指定的)Sunbet「官网」,Sunbet提供Sunbet(Sunbet)、Sunbet、申博代理合作等业务。

上一篇:金华论坛网:伊斯纳:网球可能是因疫情最后一项恢复的运动

下一篇:衢州星空棋牌:【抗击新冠肺炎疫情之下奢侈品行业这么做】奢侈品加速拥抱内地电商

网友评论