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。
JAVA面试题 启动线程是start()还是run()?为什么?的更多相关文章
- Java面试题之线程与进程的区别
进程是操作系统分配资源的最小单元: 线程是操作系统调度的最小单元: 一个程序至少有一个进程:一个进程至少有一个线程 每个进程对应一个JVM实例,多个线程共享JVM里的堆: 线程不能看做独立应用,而进程 ...
- Java面试题(全)--视频系列
此系列为面试笔试题的视频讲解,以下均为超链接,点击即可进入每个知识点的讲解. Java面试题01.面试的整体流程 Java面试题02.java的垮平台原理 Java面试题03.搭建一个java的开发环 ...
- java学习笔记14--多线程编程基础1
本文地址:http://www.cnblogs.com/archimedes/p/java-study-note14.html,转载请注明源地址. 多线程编程基础 多进程 一个独立程序的每一次运行称为 ...
- Java入门系列-21-多线程
什么是线程 在操作系统中,一个应用程序的执行实例就是进程,进程有独立的内存空间和系统资源,在任务管理器中可以看到进程. 线程是CPU调度和分派的基本单位,也是进程中执行运算的最小单位,可完成一个独立的 ...
- Java中如何使用线程
首先了解线程的状态转换图: 在Java中一个类要当做线程来使用有两种方法: 1)继承Thread类,并重写run函数 2)实现Runnable接口,并重写run函数 Java是单继承的,但某些情况下一 ...
- 为什么启动线程是start方法?
为什么启动线程是start方法 十年可见春去秋来,百年可证生老病死,千年可叹王朝更替,万年可见斗转星移. 凡人如果用一天的视野,去窥探百万年的天地,是否就如同井底之蛙? 背景:启动线程是start ...
- python的threading.Thread线程的start、run、join、setDaemon
Pycharm整体看下Thread类的内容:模拟的是Java的线程模型 表示方法method,上面的锁头表示这个是类内部的方法,从方法名字命名规范可以看出,都是_和__开头的,一个下划线表示是子类可以 ...
- Java 启动线程的方式
面试题:JAVA启动线程的方式有哪些? 1.继承Thread [java] view plaincopy public class java_thread extends Thread{ public ...
- java笔记之线程方式1启动线程
* 需求:我们要实现多线程的程序. * 如何实现呢? * 由于线程是依赖进程而存在的,所以我们应该先创建一个进程出来. * 而进程是由系统创建的,所以我们应该去调用系统功能创建一个进程. * ...
随机推荐
- makedownpad安装解锁
http://blog.csdn.net/na_beginning/article/details/53414102
- 图像滤镜艺术---Swirl滤镜
原文:图像滤镜艺术---Swirl滤镜 Swirl Filter Swirl 滤镜是实现图像围绕中心点(cenX,cenY)扭曲旋转的效果,效果图如下: 原图 效果图 代码如下: // ...
- C# 开机自动启动
if (ConfigurationManager.AppSettings["IsBoot"].ToString().Trim().ToUpper() == "TRUE&q ...
- Visual Studio 2017报表RDLC设计器与工具箱中Report Viewer问题
原文:VS2017入门 RDLC入门之01 本系列所有内容为网络收集转载,版权为原作者所有. VS2017初始安装后和VS2015一样,都没有ReportDesigner/ReportViewer R ...
- 三星860 evo 250g 开启AHCI模式读写对比
主板比较老,只支持sata2接口 换用三星860evo后跑分对比
- 解决xp越来越慢的办法(其中有些自动备份的功能)
1.减少磁盘空间占用2.终止不常用的系统服务3.安全问题4.另外一些技巧 首先问一下,你是不是很想激活XP,不...准确的说你是不是想在ms的站上能够升级.如果答案是肯定的话,那我们就先来探讨一下安装 ...
- 三种扩展 Office 软件功能的开发模型对比 – Office Add-In Model, VBA 和 VSTO
当 Office 用户需要针对文档自定义新功能时,可以求助于 VBA 或者 VSTO 两种方式.Office 2013 富客户端以后,微软为 Office 平台上的开发者提供了一种新模型 --- Of ...
- 一个类的实例化对象所占空间的大小(对象大小= vptr(可能不止一个) + 所有非静态数据成员大小 + Aligin字节大小(依赖于不同的编译器))
注意不要说类的大小,是类的对象的大小. 首先,类的大小是什么?确切的说,类只是一个类型定义,它是没有大小可言的. 用sizeof运算符对一个类型名操作,得到的是具有该类型实体的大小. 如果 Class ...
- PC-lint 简明教程(C/C++静态代码检查工具)
前言 PC-lint是一款小而强大的C/C++静态代码检查工具,它可以检查未初始化变量,数组越界,空指针等编译器很难发现的潜在错误.在很多专业的软件公司如Microsoft,PC-Lint检查无错误无 ...
- ACL 我为什么要发明一个轮子?
现在成熟的开发库与开发框架有很多,所以平时我们在开发自己的应用程序时一般直接拿来用就可以了,所以当我先是开发出 C 语言版的 acl 框架库时有人认为是这个轮子是否值得发明,而当我再开发出基于 acl ...