并发编程是Java语言的重要特性之一,“如何在Java中实现线程”是学习并发编程的入门知识,也是Java工程师面试必备的基础知识。本文从线程说起,然后用代码说明如何在Java中实现线程。

一、什么是线程?

线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。程序员可以通过它进行多处理器编程,也可以使用多线程对运算密集型任务提速。如果使用得当,线程可以有效地降低程序的开发和运维成本,同时能够提升程序的性能。

二、线程和进程有什么区别?

线程是进程的子集,一个进程可以有很多线程。每个进程都有自己的内存空间,可执行代码和唯一进程标识符(PID)。

每条线程并行执行不同的任务。不同的进程使用不同的内存空间(线程自己的堆栈),而所有的线程共享一片相同的内存空间(进程主内存)。别把它和栈内存搞混,每个线程都拥有单独的栈内存用来存储本地数据。

三、如何在Java中实现线程?

“如何在Java中实现线程”是学习并发编程入门的必备知识,对于这个问题也是众说纷纭?打开百度搜索一下,一看便知。在信息爆炸的时代,我认为像孙悟空一样有一双火眼金睛是很必要的,分辨出哪些观点更加准确,才能少走弯路。

那究竟有几种方法可以实现线程?哪一家的言论更权威,被更多的开发者所认同呢?毋庸置疑,当然是官网文档了。文档地址

如图中所示:

There are two ways to create a new thread of execution.

One is to declare a class to be a subclass of Thread. ...

The other way to create a thread is to declare a class that implements the Runnable interface. ...

现在可以肯定地说,在Java中实现线程有两种方式, 分别是继承 Thread 类和实现 Runnable 接口。下面分别用两种方式实现线程。

  • 方法一:继承Thread类。
public class MyThread extends Thread {

    public static void main(String[] args) {
new MyThread().start();
} @Override
public void run() {
System.out.println("用Thread类实现线程");
}
}
  • 方法二:实现Runnable接口。
public class MyRunnable implements Runnable {

    public static void main(String[] args) {
Thread thread = new Thread(new MyRunnable());
thread.start();
} @Override
public void run() {
System.out.println("用Runnable接口实现线程");
}
}
  • 深入分析

深入去看Thread类的源码,可以看到Thread类实现了Runnable接口。

并且Thread类重写了run方法, run 方法的代码如下:

看过源码可以发现,其实两种方法实现线程的本质是一样的,都是最终调用了 start()方法来新建线程。这两个方法的最主要区别在于 run()方法的内容来源:

继承Thread类: run()方法整体被重写;

实现Runnable接口:最终调用 target.run()。

四、实现 Runnable 接口和继承 Thread 类哪种方式更好?

Runnable和Thread两者最大的区别是Thread是类而Runnable是接口,至于用类还是用接口,取决于继承上的实际需要。Java类是单继承的,实现多个接口可以实现类似多继承的操作。

使用继承 Thread 的方式的话,那么每次想新建一个任务,只能新建一个独立的线程,而这样做的损耗会比较大。而如果采用实现Runnable接口的话,Runnable就相当于一个作业,而Thread才是真正的处理线程,我们需要的只是定义这个作业,然后将作业交给线程去处理,这样就达到了松耦合,也符合面向对象里面组合的使用。

五、总结

当下次再遇到这样的面试题的时候,可以这样硬刚面试官:

Java官方文档说明有两种方式实现线程:继承Thread和实现Runnable接口。

但是深入源码会发现,其实是一种本质方式,只能通过新建Thread类来创建线程,但是类里面的run方法有两种方式来实现,第一种是重写run方法,第二种实现Runnable接口的run方法,然后再把该runnable实例传给Thread类。

用代码说话:如何在Java中实现线程的更多相关文章

  1. 你如何在 Java 中获取线程堆栈?

    kill -3 [java pid] 不会在当前终端输出,它会输出到代码执行的或指定的地方去.比如,kill -3 tomcat pid, 输出堆栈到 log 目录下. Jstack [java pi ...

  2. java中的线程安全

    在Java中,线程的安全实际上指的是内存的安全,这是由操作系统决定的. 目前主流的操作系统都是多任务的,即多个进程同时运行.为了保证安全,每个进程只能访问分配给自己的内存空间,而不能访问别的.分配给别 ...

  3. 如何在Java中调用Python代码

    有时候,我们会碰到这样的问题:与A同学合作写代码,A同学只会写Python,而不会Java, 而你只会写Java并不擅长Python,并且发现难以用Java来重写对方的代码,这时,就不得不想方设法“调 ...

  4. 如何在 Java 中实现最小生成树算法

    定义 在一幅无向图 \(G=(V,E)\) 中,\((u, v)\) 为连接顶点 \(u\) 和顶点 \(v\) 的边,\(w(u,v)\) 为边的权重,若存在边的子集 \(T\subseteq E\ ...

  5. 如何在 Java 中实现 Dijkstra 最短路算法

    定义 最短路问题的定义为:设 \(G=(V,E)\) 为连通图,图中各边 \((v_i,v_j)\) 有权 \(l_{ij}\) (\(l_{ij}=\infty\) 表示 \(v_i,v_j\) 间 ...

  6. 如何在JAVA中实现一个固定最大size的hashMap

    如何在JAVA中实现一个固定最大size的hashMap 利用LinkedHashMap的removeEldestEntry方法,重载此方法使得这个map可以增长到最大size,之后每插入一条新的记录 ...

  7. 如何在java中使用sikuli进行自动化测试

    很早之前写过一篇介绍sikuli的文章.本文简单介绍如何在java中使用sikuli进自动化测试. 图形脚本语言sikuli sikuli IDE可以完成常见的单击.右击.移动到.拖动等鼠标操作,ja ...

  8. 如何在java中跳出当前多重嵌套循环?有几种方法?

    如何在java中跳出当前多重嵌套循环?有几种方法? - 两种方法   - 1.在外层循环定义标记          ok:          for(int i=0;i<100;i++){    ...

  9. 如何在Java中测试类是否是线程安全的

    通过优锐课的java核心笔记中,我们可以看到关于如何在java中测试类是否线程安全的一些知识点汇总,分享给大家学习参考. 线程安全性测试与典型的单线程测试不同.为了测试一个方法是否是线程安全的,我们需 ...

随机推荐

  1. Java EE.Servlet.处理请求

    Servlet的核心工作便是处理客户端提交的请求信息,生成动态响应信息返回客户端. 1.请求参数 POST方法一般用于更新服务器上的资源,当时用POST方法时,提交的数据包含在HTTP实体内,而GET ...

  2. 《VR入门系列教程》之20---使用Oculus移动端SDK

    使用Oculus移动端SDK     在基于安卓系统的GearVR上开发应用需要用到Oculus的移动端SDK,下面的网址可以下载SDK:http://developer.oculus.com     ...

  3. github项目readme.md文件如何编写

    参考链接:http://blog.csdn.net/Bone_ACE/article/details/48318675

  4. JVM指令

    本篇指令码表,参考自ASM文档手册,如果你对asm感兴趣,可到ASM官网下载手册学习. 一.本地变量操作指令(I,L,F,D,A这些前缀表示对int,long,float,double,引用进行操作) ...

  5. [转]jQuery不同版本区别

    原文转载自csdn:http://blog.csdn.net/u010167032/article/details/23666145 了解不同版本之间的差异,与助于选择适合自己项目的版本. ⒈4重要新 ...

  6. 用python实现九九乘法表输出-两种方法

    2019-08-05 思考过程:九九乘法表需要两层循环,暂且称之为内循环和外循环,因此需要写双层循环来实现. 循环有for和while两种方式. for循环的实现 for i in range(1,1 ...

  7. Adapter适配器模式--图解设计模式

    第二章: Adapter 模式 Adapter模式分为两种: 1.类适配器模式 2.委托适配器 我看的是<图解设计模式>这本书,这小鬼子说的话真难懂,只能好好看代码理解. 先说适配器模式要 ...

  8. 【React踩坑记二】react项目实现JS路由跳转

    这里使用的是4.31版本的react-router-dom "react-router-dom": "^4.3.1", 直接使用以下代码即可实现路由跳转 thi ...

  9. 如何让传统ASP.NET网站在Docker中运行

    本文主要描述如何让传统ASP.NET网站在Docker中运行,侧重Docker image 搭建. 使用条件: Docker for windows 用户切换到Windows 容器模式 Windows ...

  10. java并发编程(二十六)----ThreadLocal的使用

    其实ThreadLocal很多接触过多线程的同学都可能会很陌生,他不像current包里面那些耳熟能详的api一样在我们面前经常出现,更多的他作为一个本地类出现在系统设计里面.我们可以说一下Sprin ...