Java 中创建线程几种方式

目录

概述

一. 继承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. 代码示例

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. 代码示例

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. 简单使用
    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. 通过线程池使用
    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.rhkb.cn/news/431030.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

已解决sublime text 3 注册激活

问题&#xff1a;未激活 解决方法&#xff1a; 安装sublime3后&#xff0c;将Patch.exe文件放入sublime 安装文件下 运行Patch.exe&#xff0c;复制粘贴注册码到 preference->enter license&#xff1b;操作如下 点击“Use license”,提示如下图表示激活成功&#xff1a; 重…

Mac使用gradle编译springboot-2.7.x源码

1 开发环境&#xff1a; JDK8 ideaIU-2024.2.2 gradle-7.6.3 代理网络 2 下载springboot源码 代码仓库网址 git clone -b 2.7.x https://github.com/spring-projects/spring-boot.git3 安装gradle gradle下载网址 https://services.gradle.org/distributions/ 安装此文件指…

你的提交信息还在拖后腿?看这里,提升代码质量的绝招!

文章目录 前言一、什么是约定式提交&#xff1f;二、创建新仓库三、将代码推送到远程仓库的步骤1.检查当前远程仓库2.添加代码到暂存区3. 进行约定式提交4. 推送代码到远程仓库5. 完成推送 总结 前言 在当今软件开发领域&#xff0c;Git已经成为最广泛使用的版本控制系统之一。…

按之字形顺序打印二叉树

题目链接&#xff1a;[编程题]按之字形顺序打印二叉树 题目简单描述&#xff1a; 给定一个二叉树&#xff0c;返回该二叉树的之字形层序遍历&#xff0c;&#xff08;第一层从左向右&#xff0c;下一层从右向左&#xff0c;一直这样交替&#xff09; 思路&#xff1a; 层序…

shell文件操作

1. 使用Makefile将前面所写的项目&#xff0c;升级优化 答&#xff1a;系统刚重装 文件缺失 恕难从命

一次RPC调用过程是怎么样的?

注册中心 RPC&#xff08;Remote Procedure Call&#xff09;翻译成中文就是 {远程过程调用}。RPC 框架起到的作用就是为了实现&#xff0c;调用远程方法时&#xff0c;能够做到和调用本地方法一样&#xff0c;让开发人员更专注于业务开发&#xff0c;不用去考虑网络编程等细节…

neo4j小白入门

1.建立几个学校的节点 1.1创建一个节点的Cypher命令 create (Variable:Lable {Key1:Value,Key2,Value2}) return Variable 1.2创建一个学校的节点 create (n:School{name:清华大学,code: 10003,establishmentDate:date ("1911-04-29")})return n 1.3一次创建几个…

出现conda不是内部或外部命令,也不是可运行的程序或批处理文件。的解决办法

发现是我的环境变量不对&#xff0c;需要改成conda.exe所在的目录下 如果不知道自己conda.exe在哪的 可以下载个everything这个软件 找东西很快 找到后 点击环境变量-系统变量-Path-新建-&#xff08;你的conda.exe所在目录&#xff1a;绝对路径&#xff09; 完成上述操作…

如何通过蜂巢(容器安全)管理内部部署数据安全产品与云数据安全产品?

本文将探讨内部部署和云数据安全产品之间的主要区别。在思考这个问题之前&#xff0c;首先了解内部部署和云数据安全产品之间的主要区别。 内部部署数据安全产品意味着管理控制台位于企业客户的内部部署&#xff0c;而德迅云安全则在云中托管云数据安全产品。德迅云安全供应商通…

DERT目标检测—End-to-End Object Detection with Transformers

DERT&#xff1a;使用Transformer的端到端目标检测 论文题目&#xff1a;End-to-End Object Detection with Transformers 官方代码&#xff1a;https://github.com/facebookresearch/detr 论文题目中包括的一个创新点End to End(端到端的方法&#xff09;简单的理解就是没有使…

MISC - 第四天(OOK编码,audacity音频工具,摩斯电码,D盾,盲文识别,vmdk文件压缩)

前言 各位师傅大家好&#xff0c;我是qmx_07&#xff0c;今天继续讲解MISC知识点 FLAG 附件是一张图片&#xff0c;尝试binwalk无果 使用StegSolve工具Data Extract查看时 发现PK字段&#xff0c;是大多数压缩包的文件头点击Save Bin保存zip文件 解压缩失败使用修复软件:htt…

代码随想录Day17 图论-2

103. 水流问题 本题思路很简单 要求我们找到可以满足到达两个边界的单元格的坐标 有一个优化的思路就是 我们从边界的节点向中间遍历 然后用两个数组表示 一个是第一组边界的数组 一个是第二边界的数组 如果两个数组都遍历到了某一个单元格 就说明该单元格时满足题目要求的 #…

OpenLayers 开源的Web GIS引擎 - 添加地图控件地图控件

中心点按钮、地图放大缩小滑块、全图和比例尺控件 直接上代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.…

如何选择适合的干式电抗器?

干式电抗器是电力系统中重要的电气设备&#xff0c;主要用于限制电网中的短路电流&#xff0c;提高电力系统的稳定性和可靠性。选择适合的干式电抗器对于保障电力系统的正常运行具有重要意义。以下是选择适合的干式电抗器的一些建议&#xff1a; 1. 根据电力系统的需求选择合适…

大模型算法岗常见面试题100道(值得收藏)非常详细收藏我这一篇就够了

大模型应该是目前当之无愧的最有影响力的AI技术&#xff0c;它正在革新各个行业&#xff0c;包括自然语言处理、机器翻译、内容创作和客户服务等等&#xff0c;正在成为未来商业环境的重要组成部分。 截至目前大模型已经超过200个&#xff0c;在大模型纵横的时代&#xff0c;不…

【设计模式】创建型模式(四):建造者模式

《设计模式之创建型模式》系列&#xff0c;共包含以下文章&#xff1a; 创建型模式&#xff08;一&#xff09;&#xff1a;工厂模式创建型模式&#xff08;二&#xff09;&#xff1a;抽象工厂模式创建型模式&#xff08;三&#xff09;&#xff1a;单例模式创建型模式&#…

Android14请求动态申请存储权限

Android14请求动态申请存储权限 Android14和Android15存储权限有增加多了选择部分&#xff0c;还是全部。一个小小的存储权限真的被它玩出了花来。本来Android13就将存储权限进行了3个细分&#xff0c;是图片&#xff0c;音频还是视频文件。 步骤一&#xff1a;AndroidManife…

峟思:山洪灾害监测预警系统全面解析

在自然灾害频发的今天&#xff0c;山洪灾害以其突发性强、破坏力大而备受关注。为了有效预防和减少山洪灾害带来的损失&#xff0c;山洪灾害监测预警系统应运而生。本文将详细介绍该系统的主要组成部分、关键传感器及其工作机制&#xff0c;以期为防灾减灾工作提供有力支持。 山…

项目小总结

这段时间主要把大概的开发流程了解完毕 修改了&#xff0c;并画了几个界面 一.界面 修改为 博客主页 个人中心 二.前后端分离开发 写前端时 就可以假设拿到这些数据了 const blogData2 {blog:{id:1,title: "如何编程飞人",author_id: 1,content: "这是一篇…

最新版C/C++通过CLion2024进行Linux远程开发保姆级教学

目前来说&#xff0c;对Linux远程开发支持相对比较好的也就是Clion和VSCode了&#xff0c;这两个其实对于C和C语言开发都很友好&#xff0c;大可不必过于纠结使用那个&#xff0c;至于VS和QtCreator&#xff0c;前者太过重量级了&#xff0c;后者更是不用说&#xff0c;主要用于…