Java 中创建线程几种方式

embedded/2024/9/24 22:27:46/

目录

概述

一. 继承Thread类

1. 特点

2. 注意事项

3. 代码示例

二. 实现Runnable接口

1. 特点

2. 注意事项

3. 代码示例

三. 实现Callable接口

1. 特点

2. 注意事项

3. 代码示例


概述

在Java中,线程(Thread)是程序执行的最小单元,它允许程序在同一时间执行多个任务。Java中的线程可以由Thread类创建,也可以通过实现Runnable接口或Callable接口创建。

java中线程几种状态:

  1. 新建(New): 线程对象已经被创建,但还没有调用start()方法。

  2. 可运行(Runnable): 线程已经调用了start()方法,但还没有获得CPU时间片执行。可运行状态包括了操作系统线程的就绪(Ready)和运行(Running)状态。

  3. 阻塞(Blocked): 线程因为等待监视器锁而被阻塞,无法继续执行。

  4. 等待(Waiting): 线程通过调用wait()join()LockSupport.park()等方法进入等待状态,需要其他线程通知或中断后才可能继续执行。

  5. 超时等待(Timed Waiting): 线程通过调用带有超时参数的sleep()wait()join()LockSupport.parkNanos()LockSupport.parkUntil()等方法进入超时等待状态,超时后会自动唤醒。

  6. 终止(Terminated): 线程的run()方法执行结束,或者因异常退出了run()方法。

线程的状态枚举类 State

一. 继承Thread类

通过继承Thread类并重写run方法来创建线程,本质上继承Thread类实现线程的方式也是通过实现 Runnable 接口,

1. 特点

  • 简单性:实现线程的代码简单直观。
  • 局限性:由于Java的单继承特性,如果一个类已经继承了其他类,就不能再继承Thread类。

2. 注意事项

  • 不要调用Thread类的run方法:应该重写run方法,而不是直接调用它。
  • 使用start方法启动线程start方法会创建一个新的线程,并调用run方法。
  • 线程安全:如果线程之间需要共享数据,需要考虑线程安全问题。

3. 代码示例

java">package com.demo.thread;/*** 文件名:ThreadDemo* 创建者:* 创建时间:2024-09-22* 描述: 通过继承 Thread 类并重写run方法来创建线程*/
public class ThreadDemo extends Thread{@Overridepublic void run(){System.out.println(Thread.currentThread().getName()+"-执行run方法");}
}/*** 测试类*/
class MainThread{public static void main(String[] args) {//1.第一种方式创建线程Thread thread = new Thread(new ThreadDemo(),"线程1");thread.start(); //启动线程//2.第二种方式创建线程Thread thread2 = new Thread(new Runnable() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName()+"-执行run方法");}},"线程2");thread2.start(); //启动线程}
}

二. 实现Runnable接口

实现 Runnable 接口是Java中创建线程的另一种常见方式,这种方式更加灵活,因为它允许类继承其他类的同时实现线程功能。Runnable 接口定义了一个 run 方法,这是线程执行的入口点。

1. 特点

  • 灵活性:实现 Runnable 接口允许类继承其他类,同时实现多线程功能。
  • 线程安全:如果多个线程共享同一个 Runnable 实例,需要考虑线程安全问题。

2. 注意事项

  • 不要在 run 方法中调用 Thread.currentThread().stop():这是不推荐的做法,因为它可能会导致程序处于不确定状态。
  • 异常处理:在 run 方法中妥善处理异常,避免线程意外终止。
  • 资源清理:如果线程使用了一些资源(如文件句柄、数据库连接等),确保在线程结束时释放这些资源。

3. 代码示例

java">package com.demo.thread;/*** 文件名:RunnableDemo* 创建者:* 创建时间:2024-09-22* 描述:实现 Runnable接口创建线程*/
public class RunnableDemo implements Runnable{public void run() {System.out.println(Thread.currentThread().getName()+"-"+"执行run方法");}
}/*** 测试类*/
class MainDemo{public static void main(String[] args) {//1.第一种创建线程执行Thread thread = new Thread(new RunnableDemo(),"线程1");thread.start(); // 启动线程//2.第二种创建线程执行Thread thread2 = new Thread(new Runnable() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName()+"-执行run方法");}},"线程2");thread2.start(); // 启动线程}
}

三. 实现Callable接口

当我们需要创建一个可以返回结果的线程时,就可以使用实现了Callable接口的方式。Callable接口是在Java 5中引入的,它允许线程执行一个任务并返回一个结果,与Runnable接口相比,Callable接口的call()方法可以返回结果并抛出异常。

Callable 接口与 Runnable 接口类似,但它可以返回一个结果并且能抛出异常。Callable 通常与 FutureTask 一起使用,后者实现了 Runnable 接口,并且包装了 Callable 对象。

1. 特点

  • 返回结果Callable 任务可以返回一个结果,可以通过 FutureTask.get() 方法获取。
  • 抛出异常Callable 任务可以抛出异常,可以通过 FutureTask.get() 方法捕获。

2. 注意事项

  • 异常处理:在 call 方法中抛出的异常可以通过 FutureTask.get() 方法的调用者捕获。
  • 线程安全:如果 Callable 任务需要访问共享资源,需要考虑线程安全问题。

3. 代码示例

使用步骤:

  1. 创建一个实现 Callable 接口的类
  2. 实现 Callable 接口的 call 方法,该方法是线程执行的入口点。
  3. 创建 Callable 实例
  4. Callable 实例传递给 FutureTask 的构造器
  5. FutureTask 对象传递给 Thread 类的构造器
  6. 创建 Thread 对象
  7. 调用 Thread 对象的 start 方法来启动线程。
  1. 简单使用
    java">package com.demo.thread;import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.FutureTask;/*** 文件名:CallableDemo* 创建者:* 创建时间:2024-09-22* 描述:通过 Callable 接口实现线程创建*/
    public class CallableDemo implements Callable<String> {@Overridepublic String call() throws Exception {return "测试";}
    }/*** 测试类*/
    class MainCallable{public static void main(String[] args){//1.创建对象CallableDemo demo = new CallableDemo();FutureTask<String> futureTask = new FutureTask<>(demo);//2.创建线程Thread thread = new Thread(futureTask);thread.start();//3.获取返回结果String res;try {res = futureTask.get();} catch (InterruptedException e) {throw new RuntimeException(e);} catch (ExecutionException e) {throw new RuntimeException(e);}System.out.println("获取线程返回结果:"+res);}
    }
  2. 通过线程池使用
    java">package com.demo.thread;import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.Future;/*** 文件名:Main* 创建者:* 创建时间:2024-09-22* 描述:*/
    public class Main {public static void main(String[] args) {//1.创建一个线程池ExecutorService executorService = Executors.newSingleThreadExecutor();//2.创建Callable任务Callable<String> callableTask = () -> {Thread.sleep(2000); // 模拟长时间运行的任务return "测试";};//3.提交Callable任务并获取Future对象Future<String> future = executorService.submit(callableTask);try {//3.获取异步任务的执行结果String result = future.get(); //此方法会阻塞,直到任务执行完成System.out.println("任务执行结果: " + result);} catch (Exception e) {e.printStackTrace();} finally {//4.关闭线程池executorService.shutdown();}}
    }
    


http://www.ppmy.cn/embedded/116298.html

相关文章

MySQL-排名函数ROW_NUMBER(),RANK(),DENSE_RANK()函数的异同

MySQL-排名函数ROW_NUMBER()&#xff0c;RANK()&#xff0c;DENSE_RANK()函数的异同 前言 假设有如下表结构与数据&#xff0c;class_id表示班级&#xff0c;需求&#xff1a;现在要按照班级分组&#xff0c;每个班级的学生进行年龄从小到大排序 一、ROW_NUMBER()函数 ROW_NUM…

Haproxy搭建Web集群

目录 一、Haproxy 1.什么是Haproxy 2.Haproxy的特性 3.Haproxy负载均衡的策略&#xff08;常见&#xff09; 4.Haproxy、LVS、Nginx的区别 二、部署Haproxy 1.Haproxy服务器部署 1.1关闭防火墙以及增强功能 1.2编译安装 1.3配置Haproxy 1.4添加Haproxy服务 2…

RT_Thread内核源码分析(二)——链表和对象管理

实时操作系统基本上都是通过一些链表进行线程、信号、队列的管理&#xff0c;RT_Thread也不例外&#xff0c;本章主要讲解RT_Thread的链表结构和对象管理。 本章基于RT_Thread Nano V3.1.5版本分析 1、链表 RT_Thread使用的链表非常简单&#xff0c;链表节点只有节点指针&#…

【论文速看】DL最新进展20240924-增量语义分割、多任务分割检测、遥感目标检测

目录 【增量语义分割】【多任务】【人脸防伪】【遥感目标检测】 【增量语义分割】 AWF: Adaptive Weight Fusion for Enhanced Class Incremental Semantic Segmentation 论文链接&#xff1a;https://arxiv.org/pdf/2409.08516 代码链接&#xff1a;[无&#xff0c;但文中说会…

MYSQL基础篇

文章目录 一、函数二、约束三、多表查询四、事务总结 一、函数 substring索引值从1开始 datadiff是前一个日期减去后面一个日期 二、约束 check&#xff08;&#xff09;括号里填条件 default后面加默认值eg&#xff1a;‘1’ 三、多表查询 给表起别名就不能直接通过表面来限定…

JVM 类加载机制

什么是类加载&#xff1f; 在JVA虚拟机实现规范中&#xff0c;通过ClassLoader类加载器把*.class字节码文件&#xff08;文件流&#xff09;加载到内存&#xff0c;并对字节码文件内容进行验证、准备、解析和初始化&#xff0c;最终形成可以被虚拟机直接使用的java.lang.Class对…

ER论文阅读-Incomplete Multimodality-Diffused Emotion Recognition

基本介绍&#xff1a;NeurIPS, 2024, CCF-A 原文链接&#xff1a;https://proceedings.neurips.cc/paper_files/paper/2023/file/372cb7805eaccb2b7eed641271a30eec-Paper-Conference.pdf Abstract 人类多模态情感识别&#xff08;MER&#xff09;旨在通过多种异质模态&#x…

【工具类】——图片缩放

在java中对于图片的处理一般都是使用Graphics2D类来实现。 Graphics2D 是 Java 2D API 的核心类&#xff0c;用于在 Java 平台上渲染二维形状、文本和图像。它是 Graphics 类的扩展&#xff0c;提供了更复杂的图形操作功能&#xff0c;包括几何变换、颜色管理、文本布局等。 用…