线程的基本使用

news/2024/7/7 11:02:07/文章来源:https://www.cnblogs.com/lsran/p/18283717

线程

1.什么是线程

线程(Thread)是计算机科学中的基本概念,用于描述一个程序内部的执行路径。一个线程可以被看作是一个程序内部的独立执行流,能够单独执行代码,并与其他线程共享同一进程的资源。以下是关于线程的一些详细信息:

  1. 线程的特点
    • 轻量级:线程是比进程更小的执行单位。一个进程中可以包含多个线程,每个线程相对独立而且占用的资源较少。
    • 并发执行:多个线程可以并发执行,各自独立地执行自己的任务,可以实现多任务处理。
    • 共享内存:同一进程内的线程共享该进程的内存资源,因此可以直接访问共享变量,但也因此需要考虑线程安全性问题。
  2. 线程的创建
    • 在Java中,可以通过继承Thread类或实现Runnable接口来创建线程。
    • 继承Thread类需要重写run()方法,然后创建Thread的实例并调用start()方法来启动线程。
    • 实现Runnable接口需要实现run()方法,然后创建Thread的实例并将实现了Runnable接口的对象作为参数传递给Thread的构造函数来启动线程。
  3. 线程的生命周期
    • 线程在执行过程中会经历不同的状态,如新建、就绪、运行、阻塞和终止等状态。
    • 线程的生命周期可以通过Thread类的方法来管理和控制,比如start()方法用于启动线程,sleep()和wait()方法用于使线程休眠或等待,join()方法用于等待一个线程执行完成。
  4. 线程调度
    • 线程调度是操作系统或虚拟机对多个线程之间的执行顺序进行管理和调度的过程。
    • 线程调度策略包括抢占式调度和协作式调度,在不同的操作系统和编程环境中可能有不同的调度策略。
  5. 线程同步与线程安全
    • 多个线程访问共享数据时会引发竞争条件和数据不一致的问题,因此需要通过同步机制来确保多线程安全访问共享资源。
    • Java提供了synchronized关键字、Lock对象、volatile关键字等机制来实现线程同步,以避免多线程并发访问导致的问题。

线程是并发编程中非常重要的概念,合理使用线程可以充分利用多核处理器的性能优势,提高程序的性能和响应速度。然而,需要注意线程间的协作、同步和安全性问题,以避免因为多线程访问共享资源而导致的意外结果。

2.创建线程的方式

在Java中,有两种主要的方式来创建线程:

1.通过继承Thread类:

  • 创建一个继承自Thread类的子类,重写子类的run()方法来定义线程要执行的任务。
  • 实例化子类的对象,并调用start()方法来启动线程的执行。
public class MyThread extends Thread {public void run() {// 定义线程要执行的任务System.out.println("Thread is running");}
}// 启动线程
public static void main(String[] args) {MyThread thread = new MyThread();thread.start();
}

2.通过实现Runnable接口:

  • 创建一个实现了Runnable接口的类,实现接口中的run()方法来定义线程要执行的任务。
  • 创建Thread对象,将实现了Runnable接口的类的实例作为参数传递给Thread的构造函数,并调用start()方法来启动线程的执行。
public class MyRunnable implements Runnable {public void run() {// 定义线程要执行的任务System.out.println("Runnable is running");}
}// 启动线程
public static void main(String[] args) {MyRunnable myRunnable = new MyRunnable();Thread thread = new Thread(myRunnable);thread.start();
}

这两种方式都可以用来创建线程,但一般推荐使用实现Runnable接口的方式,因为Java不支持多重继承,而实现接口可以更灵活地扩展其他类。另外,通过实现Runnable接口还能更好地描述任务和线程之间的关系,使代码更清晰和易于维护。

在Java中,除了通过继承Thread类或实现Runnable接口来创建线程外,还可以使用Callable接口来创建线程。Callable接口是一个泛型接口,可以返回线程执行结果,并且可以抛出异常。与Runnable接口不同的是,Callable接口的call()方法可以有返回值。

下面是使用Callable接口创建线程的步骤:

  1. 创建一个实现Callable接口的类,并实现call()方法来定义线程要执行的任务。
import java.util.concurrent.Callable;public class MyCallable implements Callable<String> {public String call() throws Exception {// 定义线程要执行的任务return "Callable is running";}
}

​ 2.使用Executor框架来启动Callable任务。Executor框架是Java并发编程中用来管理线程的工具,可以在程序中方便地提交和执行线程任务。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;public class Main {public static void main(String[] args) {MyCallable myCallable = new MyCallable();// 创建线程池ExecutorService executor = Executors.newFixedThreadPool(1);// 提交Callable任务并获取Future对象Future<String> future = executor.submit(myCallable);try {// 获取线程执行结果String result = future.get();System.out.println(result);} catch (Exception e) {e.printStackTrace();}// 关闭线程池executor.shutdown();}
}

在上面的示例中,我们首先创建了一个实现Callable接口的类MyCallable,然后通过Executor框架创建了一个线程池并提交了Callable任务。最后通过Future对象获取线程的执行结果。

使用Callable接口创建线程可以更方便地获取线程的执行结果,并且可以更灵活地处理异常。相比于Runnable接口,Callable接口更适合一些需要返回结果的线程任务场景

3.Thread类中常用的方法

在Java中,Thread类提供了许多常用的方法来操作线程。以下是Thread类中常用的一些方法:

  1. start()
  • 通过调用start()方法来启动线程,使其进入就绪状态,等待CPU调度执行。
  1. run()
  • 在Thread类中,run()方法定义了线程的执行逻辑。
  1. sleep(long millis)
  • 让当前线程休眠指定的时间(以毫秒为单位)。
  1. join()
  • 等待调用join()方法的线程执行完成后,当前线程再继续执行。
  1. join(long millis)
  • 等待调用join()方法的线程执行完成,最多等待millis毫秒。
  1. interrupt()
  • 中断线程,将线程的中断标记设置为true。
  1. isInterrupted()
  • 判断线程是否被中断。
  1. getName()
  • 获取线程的名称。
  1. setName(String name)
  • 设置线程的名称。
  1. yield()
  • 让出CPU执行权,给其他线程执行机会。
  1. isAlive()
  • 判断线程是否还存活。
  1. setPriority(int priority)
  • 设置线程的优先级。
  1. getPriority()
  • 获取线程的优先级。
  1. wait()
  • 当前线程进入等待状态,直到另一个线程调用notify()或notifyAll()方法唤醒它。
  1. notify() / notifyAll()
  • 唤醒正在等待的线程。

这些是Thread类中的一些常用方法,可以帮助我们操作线程的状态和行为。根据具体的需求,我们可以选择合适的方法来控制线程的执行。

4.Runable和Callable的区别

在Java中,Runnable和Callable接口都可以用来创建多线程,但它们之间有一些区别:

  1. 返回值
  • Runnable接口中的run()方法没有返回值,而Callable接口中的call()方法可以返回一个结果。
  1. 异常处理
  • Runnable接口中的run()方法不能抛出已检查异常,但可以通过try-catch在方法内部处理异常;而Callable接口的call()方法可以抛出异常,需要通过捕获或声明抛出来处理异常。
  1. 返回结果
  • Callable接口可以返回一个结果,而Runnable接口无法直接返回结果,但可以通过共享变量或其他方式来获取线程执行结果。
  1. Future类
  • 在使用Callable接口时,可以通过Future来获取线程执行的结果,而Runnable接口没有提供类似的机制。
  1. 适用场景
  • Callable适用于需要返回结果、可能抛出异常的线程任务;而Runnable适用于简单的无需返回结果、不会抛出异常的线程任务。

总的来说,如果需要线程执行任务后返回一个结果或者抛出异常,可以使用Callable接口;如果只是简单的执行任务而不需要返回结果,可以使用Runnable接口。根据具体需求,选择适合的接口来创建线程可以使代码更加清晰和方便处理线程任务的结果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/738050.html

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

相关文章

Fastapi 脚本接口规范优化

Fastapi 脚本接口规范优化 在编写Fastapi脚本提供自动化接口操作时,我们不仅要实现接口功能实用性,也要考虑接口的规范管理,这边以Fastapi官方文档作为一个切入点。 官方接口文档 默认官方接口文档如下图所示,宛如大杂烩一样 /doc接口文档 /redoc接口文档 优化方案 1、根据…

面试官:Java类是如何被加载到内存中的?

类的生命周期都有哪些阶段?类加载的过程是怎样的?面试连环callJava类是如何被加载到内存中的? Java类的生命周期都有哪些阶段? JVM加载的class文件都有哪些来源? JVM在加载class文件时,何时判断class文件的格式是否符合要求?类生命周期 一个类从被加载到虚拟机内存开始,…

招募贴 | 第四期自动驾驶OS开发初阶营报名开启

招募贴 | 第四期自动驾驶OS开发初阶营报名开启 第四期国家智能网联汽车创新中心自动驾驶OS开发初阶训练营将于2024年7月22日开营,现已开启报名,诚邀对自动驾驶底层软件开发感兴趣的学员加入,一起驶入自动驾驶的快车道,共同探索未来的无限可能。从训练营能学到什么? 训练营…

STM32L073RZT 调试SPI问题

现象描述: spi通信一次后,第二次通信spi的SR寄存器异常0xFF31(MODF, CRCERR, RXNE),通信失败。 以下为调用流程及相关代码:NFC_ID(); NFC_REG_B_TEST();//SPI 读 void SPI_Read_Data(uint8_t* w_data, uint32_t w_size, uint8_t* r_data, uint32_t r_size) {SET_SPI_CSS(G…

Spark大数据处理:技术、应用与性能优化(全)PDF书籍推荐分享

本书从一个系统化的视角,秉承大道至简的主导思想,介绍Spark中最值得关注的内 容,讲解Spark部署、开发实战,并结合Spark的运行机制及拓展,帮读者开启Spark技术之旅。 Spark大数据处理:技术、应用与性能优化(全)PDF下载 Spark已经在全球范围内广泛使用,无论是Intel、Yahoo…

LaTeX 编辑协作平台 Overleaf 安装和使用教程

在学术界和科技行业,LaTeX 已成为撰写高质量文档的标准工具。然而,传统的 LaTeX 使用体验常常伴随着以下挑战:学习曲线陡峭 环境配置复杂 多人协作困难 实时预览不便当然,市面上不乏很多在线 LaTeX 编辑平台,但它们大多是封闭的商业服务,无法完全满足用户对数据隐私和自主…

半个月6次面试,终于进百度HR面了

和大家分享一下来自粉丝的面经投稿,他在最近半个月内疯狂的面试,光百度就约面了两个岗位,一共进行了6场面试,并且其中一个进到了 HR 面。今天和大家分享一下来自粉丝的面经投稿,他在最近半个月内疯狂的面试,光百度就约面了两个岗位,一共进行了6场面试,并且其中一个进到…

使用钉钉Oauth2授权登录Odoo配置

准备工作 需要用到的模块: Odoo/auth_oauth OCA/server-auth/auth_oidc 因为钉钉的Oauth授权流程比较特殊,需要继承改造res.users上的几个方法 models\res_users.pyclass ResUsers(models.Model):_inherit = "res.users"dingtalk_userid = fields.Char(Dingtalk Us…

推荐一款Win11主题WPF UI框架

最近在微软商店,官方上架了新款Win11风格的WPF版UI框架【WPF Gallery Preview 1.0.0.0】,这款应用引入了前沿的Fluent Design UI设计,为用户带来全新的视觉体验。最近在微软商店,官方上架了新款Win11风格的WPF版UI框架【WPF Gallery Preview 1.0.0.0】,这款应用引入了前沿的…

图论总结

重链剖分 树上修改,查询路径信息之类的 最多经过logn个轻边, 这样可以更好地划分 注意点: 修改边权可以转化到点权上面: 注意lca的位置不要修改, 应该是update(id[y]+1,id[x]) 例题: 轻重边: https://www.luogu.com.cn/problem/P7735 判断是不是重边,信息转化到点上面,…

logstach 8.6.2输出到mongo 6

logstach官网下载:https://www.elastic.co/cn/downloads/past-releases 1、查看logstach有没有自带输出到mongo的插件,到logstach安装目录/bin下cd /data/logstash-8.6.2/bin/ ./logstash-plugin list --verbose2、没有自带输出到mongo的插件就安装./logstash-plugin install…

模拟集成电路设计系列博客——8.4.3 数控振荡器

8.4.3 数控振荡器 在之前的章节中,我们介绍了一种简单得基于LC振荡器得数控振荡器方式,通过开关控制谐振电路中的电容值实现数控频率方式。 另一种更直接的利用模拟PLL中的LC振荡器VCO的方式是直接通过DAC的方式将数字码转换成模拟量,然后对电容施加控制。值得一提的是这种压…

android 性能优化 -systrace

简介: Systrace允许监视和跟踪Android系统的行为(trace)。它会指明系统都在哪些工作上花费时间、CPU周期都用在哪里,甚至可以看到每个线程、进程在指定时间内都在干嘛。它同时还会突出观测到的问题,从垃圾回收到渲染内容都可能是问题对象,甚至提供建议的解决方案。但是不能…

故地重游

近来,种种原因让我总觉得对任何事都失去了兴趣,整个人犹如失去灵魂的躯壳一般。一切都在往前走,但我想更快一些却无能为力,比较稳定的环境也就注定了过程的时长,又没有改变当下的勇气,每每思量心猿四起,无法自拔。本诗在故地重游(初到京第一工作地)所做,一步步走在那…

pip安装问题记录

【问题1】 pip安装某第三方库的时候报错:metadata-generation-failed解决办法: 1、确保你的pip和setuptools是最新版本:pip install --upgrade pip setuptools 2. setuptools版本不适配,不能进行构建: pip install --upgrade setuptools==57.5.0

P2286 [HNOI2004] 宠物收养场 题解

P2286 [HNOI2004] 宠物收养场 题解 set 做法P2286 [HNOI2004] 宠物收养场 set做法 题链\(_{洛谷}\) \(_{题库}\) 思路 一眼查找前驱后继的题。注意到一句话:那么用 set 就没有什么阻碍了,方便又快捷。 题意很简单,若宠物多则查找与人需求最接近的上下两个值,人多则找与宠…

Dijkstra算法理解-无人机路径规划

1、理解 Dijkstra算法是路径规划算法中非常经典的一种算法,在很多地方都会用到,特别是在机器人的路径规划中,基本学习机器人运动相关的都会接触到该算法。 Dijkstra算法本身的原理是基于贪心思想实现的,首先把起点到所有点的距离存下来找个最短的,然后松弛一次再找出最短的…

Three.js

右手坐标系 //每秒转一圈 const clock = new THREE.Clock() function tick() {const time = clock.getElapsedTime()mesh.rotation.y = time * Math.PI * 2 //一秒转一圈renderer.render(scene, camera)window.requestAnimationFrame(tick) } tick()const client = {x: 0,y: 0 …

关于古书介绍上“单鱼尾”是什么?

在阅读一些古书时,读的往往时某些版本的综合刊定版,而介绍有关原版时,会出现这个词语“单鱼尾”或者双鱼尾,这是什么意思呢? 搜索发现,原来古书也不是一页页,单页的,而是双页印刷,然后中间折叠,装订成册的。而折叠的具体位置在哪呢?就由鱼尾型标志标明,显然鱼尾最凹…

数据特征采样在 MySQL 同步一致性校验中的实践

本文介绍了当前DTS应用中,MySQL数据同步使用到的数据一致性校验工具,并对它的实现思路进行分享。作者:vivo 互联网存储研发团队 - Shang Yongxing本文介绍了当前DTS应用中,MySQL数据同步使用到的数据一致性校验工具,并对它的实现思路进行分享。 一、背景 在 MySQL 的使用过…