阿里后端Java面试题:启动线程是start()还是run()?为什么?

面试官:请问启动线程是start()还是run()方法,能谈谈吗?

应聘者:start()方法

当用start()开始一个线程后,线程就进入就绪状态,使线程所代表的虚拟处理机处于可运行状态,这意味着它可以由JVM调度并执行。但是这并不意味着线程就会立即运行。只有当cpu分配时间片时,这个线程获得时间片时,才开始执行run()方法。start()是方法,它调用run()方法.而run()方法是你必须重写的. run()方法中包含的是线程的主体(真正的逻辑)。

继承Thread类的启动方式

public class ThreadTest {
    public static void main(String[] args) {
        MyThread t =new MyThread();
        t.start();
    }
}
class MyThread extends Thread{
    @Override
         public void run() {
        System.out.println("Hello World!");
    }
}

实现Runnable接口的启动方式

public class ThreadTest {
    public static void main(String[] args) {
        Thread t =new Thread(new MyRunnable());
        t.start();
    }
}
class MyRunnable implements Runnable{
    @Override
         public void run() {
        System.out.println("Hello World!");
    }
}

实际上这两种启动线程的方式原理是一样的。首先都是调用本地方法启动一个线程,其次是在这个线程里执行目标对象的run()方法。那么这个目标对象是什么呢?为了弄明白这个问题,我们来看看Thread类的run()方法的实现:

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

当我们采用实现Runnable接口的方式来实现线程的情况下,在调用new Thread(Runnable target)构造器时,将实现Runnable接口的类的实例设置成了线程要执行的主体所属的目标对象target,当线程启动时,这个实例的 run()方法就被执行了。

当我们采用继承Thread的方式实现线程时,线程的这个run()方法被重写了,所以当线程启动时,执行的是这个对象自身的 run()方法。

总结起来:如果我们采用的是继承Thread类的方式,那么这个target就是线程对象自身,如果我们采用的是实现Runnable接口的方式,那么这个target就是实现了Runnable接口的类的实例。

我们再来看一道混迹于各大面试公司笔试的题目:

public class EqualsTest {
    public static void main(String args[]) {
        Thread t = new Thread() {
            public void run() {
                pong();
            }
        }
        ;
        t.run();
        System.out.print("ping");
    }
    static void pong() {
        System.out.print("pong");
    }
}

这里的标准答案是:pongping

这里直接调用线程的run方法,就相当于调用普通方法一样,由上往下执行,所以最后的结果是pongping。但是如果上面改成t.start()之后,这个结果就不固定了,因为这里有两个线程(其实还有一个守护线程,这里就先忽略),main线程和 t 线程,这两个线程获得cpu的时间就会不固定了,谁先获得CPU执行权,谁就先打印结果,所以最后的结果可能pongping也可能是pingpong。

写在最后

原文地址:https://blog.51cto.com/14409778/2420168

时间: 2024-12-18 17:43:52

阿里后端Java面试题:启动线程是start()还是run()?为什么?的相关文章

JAVA面试题 启动线程是start()还是run()?为什么?

面试官:请问启动线程是start()还是run()方法,能谈谈吗? 应聘者:start()方法 当用start()开始一个线程后,线程就进入就绪状态,使线程所代表的虚拟处理机处于可运行状态,这意味着它可以由JVM调度并执行.但是这并不意味着线程就会立即运行.只有当cpu分配时间片时,这个线程获得时间片时,才开始执行run()方法.start()是方法,它调用run()方法.而run()方法是你必须重写的. run()方法中包含的是线程的主体(真正的逻辑). 继承Thread类的启动方式 publ

整理的70道阿里高级Java面试题,都来挑战一下,看看自己有多厉害

整理的70道阿里高级Java面试题,都来挑战一下,看看自己有多厉害.1.java事件机制包括哪三个部分?分别介绍.2.为什么要使用线程池?3.线程池有什么作用?4.说说几种常见的线程池及使用场景.5.线程池都有哪几种工作队列?6.怎么理解无界队列和有界队列?7.线程池中的几种重要的参数及流程说明.8.什么是反射机制?9.说说反射机制的作用.10.反射机制会不会有性能问题?11.你怎么理解http协议?12.说说http协议的工作流程.13.http有哪些请求提交方式?14.http中的200,3

Java面试题(线程)

第一次写,写的目的就是为了帮助自己更好地查看自己学的知识,也是对自己平时学习的一些总结.可能有些地方并不是完美,覆盖的知识面不够广泛,请谅解. 问题一 线程和进程的区别: 进程:进程就是任务管理器中那些后台运行程序,进程是程序的实体. 线程:在一个完整的java程序中,开始执行是从main开始,main就是一个线程,从main开始java会同时启动垃圾回收机制,垃圾回收机制就是另一个线程.除了这两个线程,还可能存在其他线程.通过这些线程一起完成一个程序的执行. 总结:从上面来看,进程是程序的实体

Java面试题:线程的生命周期包括哪几个阶段?

面试官:您知道线程的生命周期包括哪几个阶段? 应聘者: 线程的生命周期包含5个阶段,包括:新建.就绪.运行.阻塞.销毁. 新建:就是刚使用new方法,new出来的线程: 就绪:就是调用的线程的start()方法后,这时候线程处于等待CPU分配资源阶段,谁先抢的CPU资源,谁开始执行; 运行:当就绪的线程被调度并获得CPU资源时,便进入运行状态,run方法定义了线程的操作和功能; 阻塞:在运行状态的时候,可能因为某些原因导致运行状态的线程变成了阻塞状态,比如sleep().wait()之后线程就处

十月阿里社招Java面试题:数据库+分布式+高并发+JVM+Spring

今天笔者为大家分享"阿里资深Java面试题",分别是数据库.分库分表.分布式缓存.分布式服务框架.分布式消息队列.分布式搜索引擎.高并发高可用架构设计.JVM.Spring.算法.数据结构等阿里资深java面试题,下面就随小编一起看看. 一. 数据库 使用mysq1索引都有哪些原则?索引什么数据结构?B+tree和Btree什么区别? mysq有哪些存储引擎啊?都有啥区别??要详细!! 设计高并发系统数据库层面该怎么设计???数据库锁有哪些类型?如何实现呀? 数据库事务有哪些? 二.

java学习笔记14--多线程编程基础1

本文地址:http://www.cnblogs.com/archimedes/p/java-study-note14.html,转载请注明源地址. 多线程编程基础 多进程 一个独立程序的每一次运行称为一个进程,例如:用字处理软件编辑文稿时,同时打开mp3播放程序听音乐,这两个独立的程序在同时运行,称为两个进程 进程要占用相当一部分处理器时间和内存资源 进程具有独立的内存空间 通信很不方便,编程模型比较复杂 多线程 一个程序中多段代码同时并发执行,称为多线程,线程比进程开销小,协作和数据交换容易

Java入门系列-21-多线程

什么是线程 在操作系统中,一个应用程序的执行实例就是进程,进程有独立的内存空间和系统资源,在任务管理器中可以看到进程. 线程是CPU调度和分派的基本单位,也是进程中执行运算的最小单位,可完成一个独立的顺序控制流程,当然一个进程中可以有多个线程. 多线程:一个进程中同时运行了多个线程,每个线程用来完成不同的工作.多个线程交替占用CPU资源,并非真正的并行执行. 使用多线程能充分利用CPU的资源,简化编程模型,带来良好的用户体验. 一个进程启动后拥有一个主线程,主线程用于产生其他子线程,而且主线程必

线程八大基础核心二(启动线程)

1.引子 在java多线程并发编程中,有八大基础核心.考考你:看看都有哪八大基础核心呢?它们分别是: 1.创建线程的方式 2.线程启动 3.线程停止 4.线程生命周期 5.线程相关的方法 6.线程相关的属性 7.线程异常处理 8.线程安全 今天我们从第二个基础核心开始:启动线程 2.考考你 #前情回顾: 1.在java编程语言中,创建好线程对象后,通过调用start方法,启动线程 Thread t1 = new Thread(); t1.start(); #考考你: 1.问题一:可以调用两次st

java笔记之线程方式1启动线程

* 需求:我们要实现多线程的程序. * 如何实现呢? *   由于线程是依赖进程而存在的,所以我们应该先创建一个进程出来. *   而进程是由系统创建的,所以我们应该去调用系统功能创建一个进程. *   Java是不能直接调用系统功能的,所以,我们没有办法直接实现多线程程序. *   但是呢?Java可以去调用C/C++写好的程序来实现多线程程序. *   由C/C++去调用系统功能创建进程,然后由Java去调用这样的东西, *   然后提供一些类供我们使用.我们就可以实现多线程程序了. * 那