面试官: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 方法 ~



目录
相关文章
|
7天前
|
存储 缓存 安全
【Java面试题汇总】多线程、JUC、锁篇(2023版)
线程和进程的区别、CAS的ABA问题、AQS、哪些地方使用了CAS、怎么保证线程安全、线程同步方式、synchronized的用法及原理、Lock、volatile、线程的六个状态、ThreadLocal、线程通信方式、创建方式、两种创建线程池的方法、线程池设置合适的线程数、线程安全的集合?ConcurrentHashMap、JUC
【Java面试题汇总】多线程、JUC、锁篇(2023版)
|
8天前
|
消息中间件 前端开发 NoSQL
面试官:线程池遇到未处理的异常会崩溃吗?
面试官:线程池遇到未处理的异常会崩溃吗?
38 3
面试官:线程池遇到未处理的异常会崩溃吗?
|
9天前
|
消息中间件 存储 前端开发
面试官:说说停止线程池的执行流程?
面试官:说说停止线程池的执行流程?
28 2
面试官:说说停止线程池的执行流程?
|
12天前
|
消息中间件 前端开发 NoSQL
面试官:如何实现线程池任务编排?
面试官:如何实现线程池任务编排?
21 1
面试官:如何实现线程池任务编排?
|
3天前
|
Java
深入理解Java中的多线程编程
本文将探讨Java多线程编程的核心概念和技术,包括线程的创建与管理、同步机制以及并发工具类的应用。我们将通过实例分析,帮助读者更好地理解和应用Java多线程编程,提高程序的性能和响应能力。
15 4
|
11天前
|
Java 调度 开发者
Java并发编程:深入理解线程池
在Java的世界中,线程池是提升应用性能、实现高效并发处理的关键工具。本文将深入浅出地介绍线程池的核心概念、工作原理以及如何在实际应用中有效利用线程池来优化资源管理和任务调度。通过本文的学习,读者能够掌握线程池的基本使用技巧,并理解其背后的设计哲学。
|
2天前
|
安全 Java 调度
Java 并发编程中的线程安全和性能优化
本文将深入探讨Java并发编程中的关键概念,包括线程安全、同步机制以及性能优化。我们将从基础入手,逐步解析高级技术,并通过实例展示如何在实际开发中应用这些知识。阅读完本文后,读者将对如何在多线程环境中编写高效且安全的Java代码有一个全面的了解。
|
10天前
|
缓存 监控 Java
Java中的并发编程:理解并应用线程池
在Java的并发编程中,线程池是提高应用程序性能的关键工具。本文将深入探讨如何有效利用线程池来管理资源、提升效率和简化代码结构。我们将从基础概念出发,逐步介绍线程池的配置、使用场景以及最佳实践,帮助开发者更好地掌握并发编程的核心技巧。
|
7天前
|
Java 调度 开发者
Java中的多线程基础及其应用
【9月更文挑战第13天】本文将深入探讨Java中的多线程概念,从基本理论到实际应用,带你一步步了解如何有效使用多线程来提升程序的性能。我们将通过实际代码示例,展示如何在Java中创建和管理线程,以及如何利用线程池优化资源管理。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的见解和技巧,帮助你更好地理解和应用多线程编程。
|
12天前
|
算法 Java 数据处理
Java并发编程:解锁多线程的力量
在Java的世界里,掌握并发编程是提升应用性能和响应能力的关键。本文将深入浅出地探讨如何利用Java的多线程特性来优化程序执行效率,从基础的线程创建到高级的并发工具类使用,带领读者一步步解锁Java并发编程的奥秘。你将学习到如何避免常见的并发陷阱,并实际应用这些知识来解决现实世界的问题。让我们一起开启高效编码的旅程吧!