Java面试挂在线程创建后续,不要再被八股文误导了!创建线程的方式只有1种

简介: Java面试挂在线程创建后续,不要再被八股文误导了!创建线程的方式只有1种

写在开头

在上篇博文中我们提到小伙伴去面试,面试官让说出8种线程创建的方式,而他只说出了4种,导致面试挂掉,在博文中也给出了10种线程创建的方式,但在文章的结尾我们提出:真正创建线程的方式只有1种,剩下的衍生品多是套壳,那么在这篇文章中,我们来解释一下缘由!

线程创建之源

OK!咱们闲话少叙,直接进入正题,回顾一下通过实现Runnable接口,重写run方法创建线程的方式,真的可以创建一个线程吗?来看下面这段demo。

【代码示例1】
public class Test  implements Runnable{
   

    public static void main(String[] args) {
   
        Test test = new Test();
        test.run();
    }
    @Override
    public void run() {
   
           System.out.println(Thread.currentThread().getName()+":"+"runnable线程");
    }
}
输出:
main:runnable线程

虽然这里我们实现了Runnable接口并重写了run方法,但执行结果中输出的线程却是主线程,这可我们调用普通的方法一样,仍旧依靠的主线程驱动,那怎么样创建一个线程呢?

【代码示例2】
public class Test  implements Runnable{
   

    public static void main(String[] args) {
   
        Test test = new Test();
        new Thread(test).start();
    }
    @Override
    public void run() {
   
        System.out.println(Thread.currentThread().getName()+":"+"runnable线程");
    }
}
输出:
Thread-0:runnable线程

这个demo中,我们在外面套了一层Thread,然后调用start方法,最终输出的结果就是一个全新的Thread-0线程,从而实现了线程的创建。

得出结论

我们继续换Callable、FutureTask、ThreadGroup、匿名内部类或Lambda表达式等类或接口,发现均无法直接创建一个线程,必须借助Thread的start();

而例如ExecutorService线程池、ForkJoin线程池、CompletableFuture类、Timer定时器类、parallelStream并行流等等,如果有去看过它们源码的小伙伴应该清楚,它们最终都依赖于Thread.start()方法创建线程。

因此,我们在这里可以大胆的得出这样的一个结论:

在Java中创建线程的方式只有一种:通过Thread.start()调用 start()方法,会启动一个线程并使线程进入就绪状态,当分配到时间片后开始运行。 start() 会执行线程的相应准备工作,然后自动执行 run() 方法的内容

线程体与线程的区别

文章写到这里,我们一起再来思考一个问题,既然Runnable和Callable接口和Thread类一样需要重写他们提供的run()/call()方法,又没有创建线程,那它们究竟做了什么呢?
这个直接给出答案:他们经过重写,确定了线程体,那线程体与线程又有何区别?我们来看看文心一言怎么说。
image.png

总结一句话:线程体是线程的核心部分,负责执行线程的具体任务。

所以说无论是Thread中的run还是Runnable中的run,Callable中的call方法,内部所实现的都是线程需要执行的具体内容也就是线程体

总结

基于以上的分析,若我们在面试中再次遇到:“Java线程有几种创建方式?”的考题,就可以这样回答啦:

Java中创建线程的方式有很多种,在《Java技术卷》和《Java编程思想》中提供了实现Runnable、Callable接口、继承Thread类、创建线程池这四种常见方式,我们还可以通过ForkJoin线程池、CompletableFuture类、Timer定时器类、parallelStream并行流、匿名内部类或Lambda表达式等多种方式去实现,但这些都不是真正意义上的创建线程,严格意义上,Java创建线程的方式只有一种那就是通过new Thread().start()创建,Runnable、Callable接口只是重写了线程的线程体,用来确定我们线程需要执行的内容。

结尾彩蛋

如果本篇博客对您有一定的帮助,大家记得留言+点赞+收藏呀。原创不易,转载请联系Build哥!

目录
相关文章
|
3天前
|
Oracle Java 关系型数据库
一次惨痛的面试:“网易提前批,我被虚拟线程问倒了”
【5月更文挑战第13天】一次惨痛的面试:“网易提前批,我被虚拟线程问倒了”
27 4
|
1天前
|
安全 Java 程序员
深入理解Java并发编程:线程安全与性能优化
【5月更文挑战第20天】本文将深入探讨Java并发编程的核心概念,包括线程安全和性能优化。我们将详细解析synchronized关键字、ReentrantLock类以及java.util.concurrent包中的高级工具类,如Semaphore、CountDownLatch和CyclicBarrier等。通过实例演示如何使用这些工具来提高多线程程序的性能和可靠性。
|
1天前
|
安全 算法 Java
深入理解Java并发编程:线程安全与性能优化
【5月更文挑战第20天】 在多核处理器日益普及的今天,并发编程成为了软件开发中不可忽视的重要话题。Java语言提供了丰富的并发工具和机制来帮助开发者构建高效且线程安全的应用程序。本文将探讨Java并发的核心概念,包括线程同步、锁机制、以及如何通过这些工具实现性能优化。我们将透过实例分析,揭示并发编程中的常见问题,并展示如何利用现代Java API来解决这些问题。
|
1天前
|
安全 Java 开发者
深入理解Java并发编程:线程安全与性能优化
【5月更文挑战第20天】在Java并发编程中,线程安全和性能优化是两个关键要素。本文将深入探讨Java并发编程的基本概念、线程安全的实现方法以及性能优化技巧。通过分析同步机制、锁优化、无锁数据结构和并发工具类的使用,我们将了解如何在保证线程安全的前提下,提高程序的性能。
|
1天前
|
安全 算法 Java
深入理解Java并发编程:线程安全与性能优化
【5月更文挑战第20天】 在Java开发中,正确处理并发问题对于确保应用的稳定性和提高性能至关重要。本文将深入探讨Java并发编程的核心概念——线程安全,以及如何通过各种技术和策略实现它,同时保持甚至提升系统性能。我们将分析并发问题的根源,包括共享资源的竞争条件、死锁以及线程活性问题,并探索解决方案如同步机制、锁优化、无锁数据结构和并发工具类等。文章旨在为开发者提供一个清晰的指南,帮助他们在编写多线程应用时做出明智的决策,确保应用的高效和稳定运行。
|
1天前
|
安全 Java
Java中的多线程编程:概念、实现及性能优化
【5月更文挑战第20天】在计算机科学中,多线程是一种允许程序同时执行多个任务的技术。Java作为一种广泛使用的编程语言,提供了对多线程编程的支持。本文将介绍Java中多线程的基本概念、实现方法以及性能优化策略,帮助读者更好地理解和应用多线程技术。
|
2天前
|
Java
Java一分钟之-并发编程:线程间通信(Phaser, CyclicBarrier, Semaphore)
【5月更文挑战第19天】Java并发编程中,Phaser、CyclicBarrier和Semaphore是三种强大的同步工具。Phaser用于阶段性任务协调,支持动态注册;CyclicBarrier允许线程同步执行,适合循环任务;Semaphore控制资源访问线程数,常用于限流和资源池管理。了解其使用场景、常见问题及避免策略,结合代码示例,能有效提升并发程序效率。注意异常处理和资源管理,以防止并发问题。
25 2
|
2天前
|
安全 Java 容器
Java一分钟之-并发编程:线程安全的集合类
【5月更文挑战第19天】Java提供线程安全集合类以解决并发环境中的数据一致性问题。例如,Vector是线程安全但效率低;可以使用Collections.synchronizedXxx将ArrayList或HashMap同步;ConcurrentHashMap是高效线程安全的映射;CopyOnWriteArrayList和CopyOnWriteArraySet适合读多写少场景;LinkedBlockingQueue是生产者-消费者模型中的线程安全队列。注意,过度同步可能影响性能,应尽量减少共享状态并利用并发工具类。
17 2
|
2天前
|
Java 程序员 调度
Java中的多线程编程:基础知识与实践
【5月更文挑战第19天】多线程编程是Java中的一个重要概念,它允许程序员在同一时间执行多个任务。本文将介绍Java多线程的基础知识,包括线程的创建、启动和管理,以及如何通过多线程提高程序的性能和响应性。
|
3天前
|
Java
深入理解Java并发编程:线程池的应用与优化
【5月更文挑战第18天】本文将深入探讨Java并发编程中的重要概念——线程池。我们将了解线程池的基本概念,应用场景,以及如何优化线程池的性能。通过实例分析,我们将看到线程池如何提高系统性能,减少资源消耗,并提高系统的响应速度。
13 5