面试官:Java线程有几种创建方式?

简介: 面试官:线程有几种创建方式?这个也太简单了叭~ 😝继承 Thread 类步骤如下:创建一个类继承 Thread重写 run 方法调用 Thread 类的 start 方法类图~代码如下public class MyThread extends Thread{ @Override public void run() { System.out.println(this.getClass().getSimpleName()); } public static void main(String[] args) {

面试官:线程有几种创建方式?


这个也太简单了叭~ 😝


网络异常,图片无法展示
|


继承 Thread 类


步骤如下:


  1. 创建一个类继承  Thread


  1. 重写 run 方法


  1. 调用 Thread 类的 start 方法


类图~


网络异常,图片无法展示
|


代码如下


public class MyThread extends Thread{
    @Override
    public void run() {
        System.out.println(this.getClass().getSimpleName());
    }
    public static void main(String[] args) {
        MyThread myThread=new MyThread();
        myThread.start();
    }
}
复制代码


实现 Runnable 接口


步骤如下:


  1. 创建一个类实现 Runnable


  1. 重写 run 方法


  1. 将该类传递到  Thread  类的构造函数中


  1. 调用 Thread 类的 start 方法


代码如下


public class MyRunnable implements Runnable{
    @Override
    public void run() {
        System.out.println(this.getClass().getSimpleName());
    }
    public static void main(String[] args) {
        Thread myRunable=new Thread(new MyRunnable());
        myRunable.start();
    }
}
复制代码


实现 Callable 接口,结合 Future 类获取返回值


特点:可以获取线程的执行结果


步骤如下:


  1. 创建一个类实现 Callable  


  1. 重写 call 方法


  1. 创建 FutureTask 类,将该类传递到  FutureTask 类的构造函数中


  1. FutureTask  类传递到  Thread  类的构造函数中


  1. 调用 Thread 类的 start 方法


  1. 调用  FutureTask  类的 get 方法获取线程执行结果


FutureTask  类不知道大家熟不熟悉~ ,这是它的类图😋


网络异常,图片无法展示
|


可以发现它也是实现了这个 Runnable 接口 ,对比上面发现大家都实现了这个


Runnable 接口 。


然后传参到 Thread 类的构造器中,然后再去调用 start 方法去启动线程~🐷


代码如下


/**
 * @author Java4ye
 * @date 2021/4/15 6:58
 * @微信公众号: Java4ye
 * @GitHub https://github.com/RyzeYang
 * @博客 https://blog.csdn.net/weixin_40251892
 */
public class MyCallable implements Callable<String> {
    @Override
    public String call() throws Exception {
        return this.getClass().getSimpleName();
    }
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        FutureTask<String> futureTask=new FutureTask<>(new MyCallable());
        Thread thread = new Thread(futureTask);
        thread.start();
        System.out.println(futureTask.get());
    }
}
复制代码


通过线程池创建线程


线程池常见创建的方式有 5 种,具体的讲到 线程池 篇再展开~ 😝


这里的例子使用 固定线程数量的线程池 : newFixedThreadPool


步骤如下:


  1. 使用 Executors 创建线程池


  1. 创建一个实现  Runnable  或者  Callable  接口的类


  1. 针对 没有 返回值的,有 execute  方法


  1. 针对 返回值的有 , 有 submit  方法


代码如下


execute 方式


ExecutorService executor = Executors.newFixedThreadPool(1);
executor.execute(new MyRunnable());
executor.shutdown();
复制代码


submit 方式


ExecutorService executor = Executors.newFixedThreadPool(1);
Future<String> future = executor.submit(new MyCallable());
System.out.println(future.get());
executor.shutdown();
复制代码


有几种创建方式呢


嘿嘿  让我数一数 👉  一共有 四 种


事情真的这么简单吗~


网络异常,图片无法展示
|


当我无意间打开这个 Thread 的源码时,发现它居然说 有两种方式  , 就是前两种方式


网络异常,图片无法展示
|


虽然官方文档里说两种,但是 咱们和面试官说的时候肯定是说四种呀~  😋


多多益善 哈哈哈哈  ~


网络异常,图片无法展示
|


看到这个表情包表示还没结束呢 U•ェ•*U  哈哈哈


还可以和 面试官 说说下面这种异步处理结果的 ,Future 增强版!


CompletableFuture (上面的 FutureTask  是阻塞版~)


CompletableFuture


为什么又来了一个 Future 呢?


主要是因为用 Future 获得异步执行结果时,要调用 阻塞方法get() 或者轮询


isDone() 判断是否为true,这两种方法都会导致主线程被 阻塞 ,和我们想的异步不


一样~ (我们需要它再帮我们处理下异步线程的执行结果呀😝)


所以在 JDK1.8 新引入了该类  CompletableFuture ,它实现了 Future 接口 ,又


通过 CompletionStage 接口扩展了功能,增加了异步事件,实现异步处理线程执行完


的结果,不用我们通过 Future 的阻塞方式去手动处理。


除了异步执行结果 外,它还可以 异步处理异常 ,具体看下面的例子😄


类图:


网络异常,图片无法展示
|


部分方法介绍


supplyAsync 表示创建带返回值的异步任务


runAsync 表示创建无返回值的异步任务


thenAccept  处理返回值,无返回结果


exceptionally 出现异常时,执行 exceptionally 中的回调方法。


正常例子


public class MyCompletableFuture {
    public static void main(String[] args) {
        CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> "Java4ye");
        completableFuture.thenAccept(System.out::println);
        completableFuture.exceptionally(throwable -> {
            System.out.println(throwable.getMessage());
            return throwable.getMessage();
        });
    }
}
复制代码


网络异常,图片无法展示
|


异常例子


public class MyCompletableFuture {
    public static void main(String[] args) {
        CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> ""+1/0);
        completableFuture.thenAccept(System.out::println);
        completableFuture.exceptionally(throwable -> {
            System.out.println(throwable.getMessage());
            return throwable.getMessage();
        });
    }
}
复制代码


网络异常,图片无法展示
|


嘿嘿 后面有机会再单独写一个介绍 CompletableFuture 的 ,里面还有很多方法 😝


网络异常,图片无法展示
|


总感觉这样结束也太干巴巴了  , 最后再和大家分享一道题 , 嘿嘿 你觉得答案是啥呢?


new Thread(()->{
    System.out.println("A");
}){
    @Override
    public void run() {
        System.out.println("B");
    }
}.start();
复制代码


网络异常,图片无法展示
|


嘿嘿 这里的答案是 B , 看着花里胡哨的,其实是子类重写了父类的 run 方法 ~



目录
相关文章
|
2月前
|
JSON 网络协议 安全
【Java】(10)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
196 1
|
2月前
|
JSON 网络协议 安全
【Java基础】(1)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
221 1
|
3月前
|
数据采集 存储 弹性计算
高并发Java爬虫的瓶颈分析与动态线程优化方案
高并发Java爬虫的瓶颈分析与动态线程优化方案
Java 数据库 Spring
170 0
|
3月前
|
算法 Java
Java多线程编程:实现线程间数据共享机制
以上就是Java中几种主要处理多线程序列化资源以及协调各自独立运行但需相互配合以完成任务threads 的技术手段与策略。正确应用上述技术将大大增强你程序稳定性与效率同时也降低bug出现率因此深刻理解每项技术背后理论至关重要.
276 16
|
4月前
|
缓存 并行计算 安全
关于Java多线程详解
本文深入讲解Java多线程编程,涵盖基础概念、线程创建与管理、同步机制、并发工具类、线程池、线程安全集合、实战案例及常见问题解决方案,助你掌握高性能并发编程技巧,应对多线程开发中的挑战。
|
4月前
|
数据采集 存储 前端开发
Java爬虫性能优化:多线程抓取JSP动态数据实践
Java爬虫性能优化:多线程抓取JSP动态数据实践
|
5月前
|
Java API 调度
从阻塞到畅通:Java虚拟线程开启并发新纪元
从阻塞到畅通:Java虚拟线程开启并发新纪元
376 83
|
5月前
|
安全 算法 Java
Java 多线程:线程安全与同步控制的深度解析
本文介绍了 Java 多线程开发的关键技术,涵盖线程的创建与启动、线程安全问题及其解决方案,包括 synchronized 关键字、原子类和线程间通信机制。通过示例代码讲解了多线程编程中的常见问题与优化方法,帮助开发者提升程序性能与稳定性。
236 0
|
5月前
|
存储 Java 调度
Java虚拟线程:轻量级并发的革命性突破
Java虚拟线程:轻量级并发的革命性突破
353 83