java线程的三种创建方式详细分析(全)

简介: 目录前言1. 继承Thread类2. 实现Runnable 接口3. 通过Callable和Future创建线程4. 总结前言关于线程这部分内容讲的比较多,可看我之前的文章【操作系统】线程与进程的深入剖析(全)【操作系统】守护线程和守护进程的区别对于线程Thread的分析 也可看我之前的文章java之Thread类详细分析(全)java之Thread类实战模板(全)多线程中run()和start()的异同详细分析(全)对于创建方式的汇总以及方式 可看我这篇文章的总结对比1. 继承

前言

关于线程这部分内容讲的比较多,可看我之前的文章

  1. 【操作系统】线程与进程的深入剖析(全)
  2. 【操作系统】守护线程和守护进程的区别

对于线程Thread的分析 也可看我之前的文章

  1. java之Thread类详细分析(全)
  2. java之Thread类实战模板(全)
  3. 多线程中run()和start()的异同详细分析(全)

对于创建方式的汇总以及方式 可看我这篇文章的总结对比

1. 继承Thread类

定义Thread类的子类,并重写该类的run方法

class MyThread extends Thread{  
      @Override
      public void run() {
       //要运行的代码
    }
}
new MyThread().start()  ;   

2. 实现Runnable 接口

class Mythread implements Runnable {
     @Override
    public void run() {
        //方法 
    }

}

3. 通过Callable和Future创建线程

//实现Callable接口
class MyThread2 implements Callable {

    @Override
    public Integer call() throws Exception {
        return 200;
    }
}
  • [ ] 不可以像下面这么创建

不可以new Thread(new MyThread2(),"BB").start();
因为Thread的构造函数中没有Callable接口的参数设置

FutureTask的构造方法有

  • FutureTask(Callable<> callable) 创建一个FutureTask,一旦运行就执行给定的Callable
  • FutureTask(Runnable runnable,V result)创建一个FutureTask,一旦运行就执行给定的Ru你那边了,并安排成功完成时get返回给定的结果

其他常用的代码:
get()获取结果
isDone()判断是否计算结束

FutureTask 具体实现方法可以有两种方式(此处用的泛型参数)
第一种是

//实现Callable接口
class MyThread2 implements Callable {

    @Override
    public Integer call() throws Exception {
        return 200;
    }
}

FutureTask<Integer> futureTask1 = new FutureTask<>(new MyThread2());

第二种是

//lam表达式
FutureTask<Integer> futureTask2 = new FutureTask<>(()->{
    System.out.println(Thread.currentThread().getName()+" come in callable");
    return 1024;
});

创建线程new Thread(futureTask2,"lucy").start();
获取结果System.out.println(futureTask2.get());

所谓的FutureTask是在不影响主任务的同时,开启单线程完成某个特别的任务,之后主线程续上单线程的结果即可(该单线程汇总给主线程只需要一次即可)
如果之后主线程在开启该单线程,可以直接获得结果,因为之前已经执行过一次了

具体完整代码案例

//比较两个接口
//实现Runnable接口
class MyThread1 implements Runnable {
    @Override
    public void run() {

    }
}

//实现Callable接口
class MyThread2 implements Callable {

    @Override
    public Integer call() throws Exception {
        System.out.println(Thread.currentThread().getName()+" come in callable");
        return 200;
    }
}

public class Demo1 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //Runnable接口创建线程
        new Thread(new MyThread1(),"AA").start();

        //Callable接口,报错
       // new Thread(new MyThread2(),"BB").start();

        //FutureTask
        FutureTask<Integer> futureTask1 = new FutureTask<>(new MyThread2());

        //lam表达式
        FutureTask<Integer> futureTask2 = new FutureTask<>(()->{
            System.out.println(Thread.currentThread().getName()+" come in callable");
            return 1024;
        });

        //创建一个线程
        new Thread(futureTask2,"lucy").start();
        new Thread(futureTask1,"mary").start();

//        while(!futureTask2.isDone()) {
//            System.out.println("wait.....");
//        }
        //调用FutureTask的get方法
        System.out.println(futureTask2.get());

        System.out.println(futureTask1.get());

        System.out.println(Thread.currentThread().getName()+" come over");
       }
}

代码截图
在这里插入图片描述

4. 总结

比较Runnable接口和Callable接口

  • Callable中的call()计算结果,如果无法计算结果,会抛出异常
  • Runnable中的run()使用实现接口Runnable的对象创建一个线程时,启动该线程将导致在独立执行的线程中调用该对象的run方法
  • 总的来说:run()没有返回值,不会抛出异常。而call()有返回值,会抛出异常

Callable规定(重写)的方法是call(),Runnable规定(重写)的方法是run()

相关文章
|
4天前
|
Java 程序员 开发者
Java社招面试题:一个线程运行时发生异常会怎样?
大家好,我是小米。今天分享一个经典的 Java 面试题:线程运行时发生异常,程序会怎样处理?此问题考察 Java 线程和异常处理机制的理解。线程发生异常,默认会导致线程终止,但可以通过 try-catch 捕获并处理,避免影响其他线程。未捕获的异常可通过 Thread.UncaughtExceptionHandler 处理。线程池中的异常会被自动处理,不影响任务执行。希望这篇文章能帮助你深入理解 Java 线程异常处理机制,为面试做好准备。如果你觉得有帮助,欢迎收藏、转发!
45 14
|
7天前
|
安全 Java 程序员
Java 面试必问!线程构造方法和静态块的执行线程到底是谁?
大家好,我是小米。今天聊聊Java多线程面试题:线程类的构造方法和静态块是由哪个线程调用的?构造方法由创建线程实例的主线程调用,静态块在类加载时由主线程调用。理解这些细节有助于掌握Java多线程机制。下期再见! 简介: 本文通过一个常见的Java多线程面试题,详细讲解了线程类的构造方法和静态块是由哪个线程调用的。构造方法由创建线程实例的主线程调用,静态块在类加载时由主线程调用。理解这些细节对掌握Java多线程编程至关重要。
37 13
|
8天前
|
安全 Java 开发者
【JAVA】封装多线程原理
Java 中的多线程封装旨在简化使用、提高安全性和增强可维护性。通过抽象和隐藏底层细节,提供简洁接口。常见封装方式包括基于 Runnable 和 Callable 接口的任务封装,以及线程池的封装。Runnable 适用于无返回值任务,Callable 支持有返回值任务。线程池(如 ExecutorService)则用于管理和复用线程,减少性能开销。示例代码展示了如何实现这些封装,使多线程编程更加高效和安全。
|
18天前
|
并行计算 安全 Java
Python GIL(全局解释器锁)机制对多线程性能影响的深度分析
在Python开发中,GIL(全局解释器锁)一直备受关注。本文基于CPython解释器,探讨GIL的技术本质及其对程序性能的影响。GIL确保同一时刻只有一个线程执行代码,以保护内存管理的安全性,但也限制了多线程并行计算的效率。文章分析了GIL的必要性、局限性,并介绍了多进程、异步编程等替代方案。尽管Python 3.13计划移除GIL,但该特性至少要到2028年才会默认禁用,因此理解GIL仍至关重要。
96 16
Python GIL(全局解释器锁)机制对多线程性能影响的深度分析
|
30天前
|
存储 Java 开发者
【潜意识Java】深入详细理解分析Java中的toString()方法重写完整笔记总结,超级详细。
本文详细介绍了 Java 中 `toString()` 方法的重写技巧及其重要
51 10
【潜意识Java】深入详细理解分析Java中的toString()方法重写完整笔记总结,超级详细。
|
30天前
|
Java 数据库连接 数据库
【潜意识Java】深度分析黑马项目《苍穹外卖》在Java学习中的重要性
《苍穹外卖》项目对Java学习至关重要。它涵盖了用户管理、商品查询、订单处理等模块,涉及Spring Boot、MyBatis、Redis等技术栈。
84 4
|
30天前
|
Java 应用服务中间件 API
【潜意识Java】javaee中的SpringBoot在Java 开发中的应用与详细分析
本文介绍了 Spring Boot 的核心概念和使用场景,并通过一个实战项目演示了如何构建一个简单的 RESTful API。
41 5
|
30天前
|
人工智能 自然语言处理 搜索推荐
【潜意识Java】了解并详细分析Java与AIGC的结合应用和使用方式
本文介绍了如何将Java与AIGC(人工智能生成内容)技术结合,实现智能文本生成。
61 5
|
30天前
|
SQL Java 数据库连接
【潜意识Java】Java中JDBC过时方法的替代方案以及JDBC为什么过时详细分析
本文介绍了JDBC中一些常见过时方法及其替代方案。
41 5
|
30天前
|
Java 数据库连接 数据库
【潜意识Java】使用 Ruoyi 框架开发企业级应用,从零开始的实践指南和分析问题
本文介绍了基于Spring Boot的开源企业级框架Ruoyi,涵盖环境搭建、项目初始化及用户管理模块的创建。
139 4

热门文章

最新文章