目录

    • 1、Oracle官网的文档是如何写的?
    • 2、两种方法的对比
    • 3、思考题:同时用两种方法会怎么样?
    • 4、总结:最精准的描述
    • 5、典型错误观点分析
    • 6、典型错误观点总结
    • 7、实现多线程——常见面试问题

1、Oracle官网的文档是如何写的?

  • 方法一:实现Runnable接口
  • 方法二:继承Thread类

实现Runnable接口

package threadcoreknowledge.createthreads;/*** 描述: 用Runnable方式创建线程*/
public class RunnableStyle implements Runnable{public static void main(String[] args) {Thread thread = new Thread(new RunnableStyle());thread.start();}public void run() {System.out.println("用Runnable方式创建线程");}
}

继承Thread类

package threadcoreknowledge.createthreads;/*** 描述:  用Thread方式实现线程*/
public class ThreadStyle extends Thread{@Overridepublic void run() {System.out.println("用Thread方式实现线程");}public static void main(String[] args) {new ThreadStyle().start(); }
}

2、两种方法的对比

方法1(实现Runnable接口)更好。

方法2的缺点:

  • 从代码的架构来考虑,具体执行的任务(run方法里面的内容)应该是和Thread解耦的,不应该把这两件事情混为一谈;
  • 从资源的节约上,继承了 Thread 类,每次我们想新建一个任务只能去新建一个独立的线程,而新建一个独立的线程损耗是十分大的(因为需要去创建,销毁);
  • 继承了Thread 类,由于Java不支持双继承,导致这个类无法去继承其他类了,这大大限制了代码的可扩性。

两种方法的本质对比

  • 方法一:最终调用target.run();
    @Overridepublic void run() {if (target != null) {target.run();}}
  • 方法二:run()整个都被重写

3、思考题:同时用两种方法会怎么样?

package threadcoreknowledge.createthreads;/*** 描述  同时使用Runnable和Thread两种实现线程的方式*/
public class BothRunnableThread {public static void main(String[] args) {new Thread(new Runnable() {  //传入Runnable对象@Overridepublic void run() {System.out.println("我来自Runnable");}}){@Override             //重写run()方法public void run() {          System.out.println("我来自Thread");}}.start();}
}

代码执行结果:

从面向对象的思想去考虑: 因为我们重写了run()方法,所以导致Thread的三行run()方法代码不再存在,即使传入传入Runnable对象,它也不再执行。

4、总结:最精准的描述

1、通常我们可以分为两类,Orracle也是这么说的

2、准确的讲,创建线程只有—种方式那就是构造Thread类,而实现线程的执行单元有两种方式

  • 方法一:实现Runnable接口的run方法,并把Runnable实例传给Thread类;
  • 方法二:重写Thread的run方法(继承Thread类)。

5、典型错误观点分析

1、“线程池创建线程也算是一种新建线程的方式”

package threadcoreknowledge.wrongways;import javafx.concurrent.Task;import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class ThreadPools {public static void main(String[] args) {ExecutorService executorService = Executors.newCachedThreadPool();for (int i = 0; i < 1000; i++) {executorService.submit(new Tasks() {});}}
}
class Tasks implements Runnable{@Overridepublic void run() {try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName());}
}

代码执行结果:

public Thread newThread(Runnable r) {Thread t = new Thread(group, r,namePrefix + threadNumber.getAndIncrement(),0);if (t.isDaemon())t.setDaemon(false);if (t.getPriority() != Thread.NORM_PRIORITY)t.setPriority(Thread.NORM_PRIORITY);return t;
}

点进去源码可以看到,线程池本质创建线程的方法是new Thread,因此这并不是一种新的创建线程方式 。

2、“通过Callable和FutureTask创建线程,也算是一种新建线程的方式”

本质是实现Runnable接口和继承Thread类实现的。

3、“无返回值是实现runnable接口,有返回值是实现callable接口,所以callable是新的实现线程的方式”

本质依旧是实现Runnable接口和继承Thread类实现的。

4、定时器

package threadcoreknowledge.wrongways;import java.util.Timer;
import java.util.TimerTask;/*** 描述:      定时器创建线程*/
public class DemoTimerTask {public static void main(String[] args) {Timer timer = new Timer();timer.scheduleAtFixedRate(new TimerTask() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName());}},1000,1000);}
}

代码执行结果:

5、匿名内部类

package threadcoreknowledge.wrongways;public class AnonymousInnerClassDemo {public static void main(String[] args) {new Thread(){@Overridepublic void run() {System.out.println(Thread.currentThread().getName());}}.start();new Thread(new Runnable() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName());}}).start();}
}

代码执行结果:

本质一样。

6、Lambda表达式

package threadcoreknowledge.wrongways;public class Lambda {public static void main(String[] args) {new Thread(()-> System.out.println(Thread.currentThread().getName())).start();}
}

代码执行结果:

本质一样。

6、典型错误观点总结

多线程的实现方式,在代码中写法千变万化,但其本质万变不离其宗。他们通过各种各样的包装,比如线程池,定时器,包装的外表好像是实现线程池的一种方式,但是我们打开包装透过源码去看到他最终实现的道理的话,本质其实是实现Runnable接口和继承Thread类。

7、实现多线程——常见面试问题

有多少种实现线程的方法?思路有5点:

  1. 从不同的角度看,会有不同的答案。
  2. 典型答案是两种
  3. 我们看原理,两种本质都是一样的
  4. 具体展开说其他方式
  5. 结论

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

  1. 从代码架构角度
  2. 新建线程的损耗
  3. Java不支持双继承

实现多线程的方法到底有1种还是2种还是4种?相关推荐

  1. 利用多线程解决多业务不同定时区间歇触发问题的一种方法

    利用多线程解决多业务不同定时区间歇触发问题的一种方法 参考文章: (1)利用多线程解决多业务不同定时区间歇触发问题的一种方法 (2)https://www.cnblogs.com/naaoveGIS/ ...

  2. python多线程实现方法_Python3 多线程的两种实现方式

    最近学习 Python3 ,希望能掌握多线程的使用,在此做个笔记.同时也希望Python 牛人指点错误.关于线程的概念,前面简单总结了一下 java 的多线程,传送门:java 多线程概念,三种创建多 ...

  3. 实现多线程的方法有哪几种?

    1)实现Runnable接口,并实现该接口的run()方法. 自定义类并实现Runnable接口,实现run()方法 创建Thread对象,用实现Runnable接口的对象作为参数实例化该Thread ...

  4. java中实现多线程的方法有哪几种

    实现多线程的方法有三种: 实现Runnable接口,并实现接口的run()方法 继承Thread类,重写run方法 实现Callable接口,重写call()方法 实现Runnable接口,并实现接口 ...

  5. Java多线程优化方法及使用方式

    一.多线程介绍 在编程中,我们不可逃避的会遇到多线程的编程问题,因为在大多数的业务系统中需要并发处理,如果是在并发的场景中,多线程就非常重要了.另外,我们在面试的时候,面试官通常也会问到我们关于多线程 ...

  6. Qt中使用多线程的一些心得(一)——继承QThread的多线程使用方法

    一 前言 二Qt多线程方法一 继承QThread 2.1使用多线程的原因分析 2.2 写一个继承于QThread的线程 三 总结 一 前言   本篇文章部分内容参考了该博文:传送门.   Qt中有两种 ...

  7. 深入探索多线程优化方法

    前言 什么是线程的概念我就不在介绍,不懂的自行百度,我想百分之九十九的人都是知道的,至于多线程,通俗的就是有很多的线程在一起工作从而完成某一件事,从而提升效率.这就是使用多线程的好处之一,举个列子,一 ...

  8. Java多线程(一)——多线程实现方法和生命周期

    目录 一.引言 二.多进程与多线程 三.实现方法 1.继承Thread接口 2.实现runnable接口,传入Thread运行 3.注意 四.生命周期 五.总结 一.引言 之前多线程了解的基本是皮毛, ...

  9. QT 中多线程实现方法总结

    第一: 用QtConcurrentRun类,适合在另一个线程中运行一个函数.不用继承类,很方便 第二:用QRunnable和QThreadPool结合.继承QRunnable,重写run函数,然后用Q ...

最新文章

  1. python之人脸识别
  2. QQ开心农场外挂软件设计思路
  3. MathType插入带序号公式的两种方法
  4. 使用Hadoop自带的例子wordcount实现词频统计
  5. java main spring_分享通过在java main函数中执行spring的代码
  6. 一些有趣的 CSS 魔法和布局(下)(结尾有岗位内推哦~)
  7. 昨天凌晨故宫网站崩了,被众多人“围攻”!留言亮了...
  8. Python实现图像信息隐藏
  9. JDK8启动时,参数传递过程
  10. html在线比对工具,在线文本对比工具(mergely示例)
  11. 未授权访问漏洞测试方法及修复方案
  12. Link第一次打包与部署笔记
  13. 鸿蒙HarmonyOS开发环境初识及搭建
  14. C语言机器人视觉系统原理,机器人视觉系统工作原理
  15. jsrun怎么拿里面的代码?
  16. 清除win+r的记录
  17. SQL Server研习录(08)——LEFT()函数
  18. html5 游戏 限制,HTML5新技术让游戏解决了三个大问题
  19. @value()注解
  20. Python之子域名查询

热门文章

  1. 如何设置u盘写保护防止u盘拷贝文件
  2. 关于.length和.length()
  3. 纳滤膜分离技术用于制药提纯精制处理 稳定可靠
  4. 由一个误操作引起的对linux下mv命令的使用总结
  5. 怎么把ofd转换成PDF文件?分享给你个好用的方法。
  6. substratum android8,substratumlite主题管理
  7. 概率论 1 随机试验 样本空间 随机事件事件间的运算
  8. n子棋,你能下赢电脑吗,来玩玩吧
  9. 可追踪评估模型TAM1
  10. 2021年京东最新炸年兽活动用脚本会怎样?JD炸年兽活动参与教程