带你整理面试过程中关于Java 中多线程的创建方式的最全整理

Posted 南淮北安

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了带你整理面试过程中关于Java 中多线程的创建方式的最全整理相关的知识,希望对你有一定的参考价值。

文章目录

一、Java线程的创建方式

扩展学习:一篇文章带你搞定 Java 中多线程的实现(Thread,Runnable)

常见的Java线程的4种创建方式分别为:继承Thread类、实现Runnable接口、通过ExecutorService和Callable<Class>实现有返回值的线程、基于线程池,如图3-1所示。

二、继承Thread类

Thread类实现了Runnable接口并定义了操作线程的一些方法,我们可以通过继承Thread类的方式创建一个线程。

具体实现为创建一个类并继承Thread接口,然后实例化线程对象并调用start方法启动线程。start方法是一个native方法,通过在操作系统上启动一个新线程,并最终执行run方法来启动一个线程。run方法内的代码是线程类的具体实现逻辑。

class MyThread extends Thread//继承 Thread 类
    private String name;
    public MyThread(String name)
        this.name = name;
    
    public void run()//覆写 Thread 类中的 run() 方法
        for(int i=0;i<10;i++)//循环 10 次输出
            System.out.println(name + "运行,i = " + i);
        
    


public class Root
    public static void main(String[] args) 
        MyThread mt1 = new MyThread("线程 A");//实例化对象
        MyThread mt2 = new MyThread("线程 B");//实例化对象
        mt1.start();//启动多线程
        mt2.start();//启动多线程
    


以上代码定义了一个名为MyThread 的线程类,该类继承了Thread,run方法内的代码为线程的具体执行逻辑,在使用该线程时只需新建一个该线程的对象并调用其start方法即可。

三、实现 Runnable 接口

基于Java编程语言的规范,如果子类已经继承(extends)了一个类,就无法再直接继承Thread类,此时可以通过实现Runnable接口创建线程。

具体的实现过程为:通过实现Runnable接口创建ChildrenClassThread线程,实例化名称为childrenThread的线程实例,创建Thread类的实例并传入childrenThread线程实例,调用线程的start方法启动线程。具体的实现代码如下:

class MyThread implements Runnable//继承 Runnable 接口
    private String name;
    public MyThread(String name)
        this.name = name;
    
    public void run()//覆写  run() 方法
        for(int i=0;i<5;i++)//循环 10 次输出
            System.out.println(name + "运行,i = " + i);
        
    

public class Root
    public static void main(String[] args) 
        MyThread my1 = new MyThread("线程 A");//实例化Runnable子类对象
        MyThread my2 = new MyThread("线程 B");//实例化Runnable子类对象
        Thread t1 = new Thread(my1);//实例化 Thread 类对象
        Thread t2 = new Thread(my2);//实例化 Thread 类对象
        t1.start();//启动多线程
        t2.start();//启动多线程
    

事实上,在传入一个实现了Runnable的线程实例 target 给 Thread 后,Thread的run方法在执行时就会调用target.run方法并执行该线程具体的实现逻辑。在JDK源码中,run方法的实现代码如下:

四、通过ExecutorService和Callable<Class>实现有返回值的线程

有时,我们需要在主线程中开启多个线程并发执行一个任务,然后收集各个线程执行返回的结果并将最终结果汇总起来,这时就要用到Callable接口。

具体的实现方法为:创建一个类并实现Callable接口,在call方法中实现具体的运算逻辑并返回计算结果。

具体的调用过程为:创建一个线程池、一个用于接收返回结果的Future List及Callable线程实例,使用线程池提交任务并将线程执行之后的结果保存在Future中,在线程执行结束后遍历Future List中的Future对象,在该对象上调用get方法就可以获取Callable线程任务返回的数据并汇总结果,实现代码如下:

创建一个类实现 Callable 接口,覆写它的 call 方法,调用时需要一个 Future 类型的 list用于接收返回结果和一个Callable 类的实例。最后调用 list 中的 Future 对象的get方法即可得到线程的返回结果。


五、基于线程池

深入学习可参考:一篇文章带你深入了解多线程中线程复用:线程池

线程是非常宝贵的计算资源,在每次需要时创建并在运行结束后销毁是非常浪费资源的。我们可以使用缓存策略并使用线程池来创建线程,具体过程为创建一个线程池并用该线程池提交线程任务,实现代码如下:

六、面试题

  1. 创建线程池的几种方式?(阿里)

七、Thread 和 Runnable 的区别

(1)使用的区别:Thread是继承的关系,Runnable 是实现关系,多继承需要使用 Runnable 来实现

(2)Thread 不支持共享数据,Runnable 支持共享数据

八、如何实现线程池里的两个线程并行执行,谁先执行完毕用谁的结果?

关键是利用了 Callable 接口实现

Callable 用于产生结果,Future 用于 获取结果

利用 isDone 方法判断执行结果,一旦一个任务执行完毕,就调用cancel 方法对另一个任务进行取消

最后利用 get 方法获取执行结果

以上是关于带你整理面试过程中关于Java 中多线程的创建方式的最全整理的主要内容,如果未能解决你的问题,请参考以下文章

带你整理面试过程中关于多线程的编程问题

带你整理面试过程中关于 Java 中的 异常分类及处理的相关知识

带你整理面试过程中关于 Java 中的集合 List,Queue,Set的相关知识点

带你整理面试过程中关于JVM 的运行机制多线程和 JVM 的内存区域的相关知识点

带你整理面试过程中关于ThreadLocal的相关知识

带你整理面试过程中关于 JVM 中分代收集算法分区收集算法和垃圾收集器的相关知识