【从零开始学习JAVA | 第三十八篇】应用多线程

目录

前言:

多线程的实现方式:

Thread常见的成员方法:

总结:


前言:

           多线程的引入不仅仅是提高计算机处理能力的技术手段,更是适应当前时代对效率和性能要求的必然选择。在本文中,我们将深入探讨多线程的应用和实践,帮助读者更好地理解和应用多线程技术,提升计算机的处理能力,迎接挑战的世界。"

多线程的实现方式:

        1.继承Thread类:你可以创建一个类并继承Thread类,然后重写run()方法,在run()方法中定义线程要执行的任务。通过创建该类的实例,并调用start()方法,可以启动一个新的线程执行run()方法中的任务。

示例代码:

class MyThread extends Thread {public void run() {// 定义线程要执行的任务System.out.println("线程执行任务");}
}public class MainClass {public static void main(String[] args) {// 创建线程并启动MyThread thread = new MyThread();thread.start();}
}

        2.实现Runnable接口:你可以创建一个类实现Runnable接口,然后实现run()方法,再通过创建Thread对象,并将Runnable对象作为参数传递给Thread的构造函数,创建一个新的线程。

示例代码:

class MyRunnable implements Runnable {public void run() {// 定义线程要执行的任务System.out.println("线程执行任务");}
}public class MainClass {public static void main(String[] args) {// 创建线程并启动MyRunnable runnable = new MyRunnable();Thread thread = new Thread(runnable);thread.start();}
}

        3.使用Executor框架:Java提供了Executor框架,它是高级线程管理的一种方式。通过Executor,你可以使用线程池来管理和执行多个线程任务,提供更好的线程控制和资源管理。

示例代码:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class MainClass {public static void main(String[] args) {// 创建线程池ExecutorService executor = Executors.newFixedThreadPool(5);// 提交任务executor.execute(new Runnable(){public void run() {// 定义线程要执行的任务System.out.println("线程执行任务");}});// 关闭线程池executor.shutdown();}
}

         4.使用Callable 和 Future 接口方式实现:当需要在线程执行完毕后获取返回结果时,可以使用Callable和Future接口来实现多线程。Callable是一个带有返回结果的任务,可以通过call()方法执行任务并返回结果。Future表示一个异步执行的任务,可以通过get()方法获取任务的返回结果。

这种方式的优点就在于:可以获取多线程的执行结果 

示例代码:

class MyCallable implements Callable<Integer> {public Integer call() throws Exception {// 定义线程要执行的任务,并返回结果return 42;}
}public class MainClass {public static void main(String[] args) {// 创建线程池ExecutorService executor = Executors.newSingleThreadExecutor();// 提交Callable任务Future<Integer> future = executor.submit(new MyCallable());// 等待并获取结果try {Integer result = future.get();System.out.println("线程执行任务的结果为: " + result);} catch (InterruptedException | ExecutionException e) {e.printStackTrace();}// 关闭线程池executor.shutdown();}
}

Thread常见的成员方法:

  • start(): 启动线程,使线程进入可运行状态,具体执行由操作系统调度。
  • run(): 线程执行的任务代码,通常通过重写该方法来定义线程要执行的逻辑。
  • sleep(long millis): 让当前线程休眠指定的毫秒数,暂停线程的执行。
  • join(): 等待线程执行完成,即等待线程终止。
  • yield(): 暂停当前正在执行的线程,并允许其他线程执行。
  • isAlive(): 判断线程是否还活着。
  • interrupt(): 中断线程,向线程发送一个中断信号,但并不一定终止线程的执行。
  • isInterrupted(): 判断线程是否被中断。
  • setName(String name): 设置线程的名称。
  • getName(): 获取线程的名称。
  • suspend(): 不推荐使用,暂停线程的执行。
  • resume(): 不推荐使用,恢复线程的执行。
  • setPriority(int priority): 设置线程的优先级,取值范围为1-10,默认为5。
  • getPriority(): 获取线程的优先级。
  • setDaemon(boolean on)设置为守护线程

我们再单独介绍一下几个常用并且不容易理解的成员方法:

1.setPriority(int priority)getPriority()

setPriority(int priority)方法用于设置线程的优先级,参数priority表示线程的优先级,取值范围为1-10,优先级默认为5。其中,1表示最低优先级,10表示最高优先级。

getPriority()方法用于获取线程的优先级,返回值为线程的优先级。

线程的优先级用于指定线程在竞争CPU资源时的优先级顺序。然而,优先级并不是绝对的执行顺序,仅作为建议给操作系统进行线程调度。

优先级的出现是因为我们JAVA中的线程在被CPU调度的时候,采用的是抢占式调度,也就是优先级越高,越容易抢到调度机会,而除了抢占式调度之外,我们还有非抢占调度,也就是CPU对线程轮流调度,不存在随机。

需要注意以下几点:

  1. 不同操作系统对线程优先级的处理可能有所不同。
  2. 线程的优先级不能保证一定按照预期执行,因为优先级可能受到操作系统调度算法的影响。
  3. 不应该过分依赖线程的优先级来实现业务逻辑,因为这可能导致代码的可移植性差。

一般来说,应用程序中使用默认优先级即可,除非有特殊需求。同时,应避免过于频繁地修改线程的优先级,以免导致优先级倾斜等问题。

2.setDaemon(boolean on)

setDaemon(boolean on)是Thread类提供的一个方法,用于设置线程的守护状态。当一个线程被设置为守护线程时,它会成为JVM中所有非守护线程的"服务员",在所有非守护线程结束后,JVM会自动退出,从而终止守护线程的执行。

具体来说,守护线程的特点如下:

  1. 守护线程通常用来提供后台服务或辅助功能,不影响程序的主要业务逻辑。
  2. 守护线程并不会影响JVM的正常终止,即使还有守护线程在执行,JVM也会自动退出。
  3. 当所有非守护线程结束后,守护线程会被自动终止,不会等待任务完成。

使用setDaemon(true)将线程设置为守护线程,使用setDaemon(false)将线程设置为用户线程(默认值)。

需要注意以下几点:

  1. setDaemon()方法只能在线程启动之前调用,一旦线程启动后,不能再修改守护状态。
  2. 守护线程不能持有任何可以独占资源的锁,因为它们可能会在任何时刻被终止,这样可能导致资源不正确释放或状态不一致的问题。
  3. 守护线程并不保证会执行完它们的任务,因此在编写守护线程时要特别小心,确保它们不会影响到程序的正确执行。

守护线程主要用于在后台提供服务或执行一些不断运行的任务,比如垃圾回收线程、定时任务线程等。一般情况下,我们在主线程中创建的线程都是用户线程,即非守护线程。

3.join()与yield()

join()与yield()都是用于线程的控制和协作的方法。

  1. join()

    • join()方法用于等待调用线程完成其执行,然后再继续执行当前线程。
    • 在一个线程A中调用另一个线程B的join()方法会使当前线程A阻塞,直到线程B执行完成。
    • 这通常用于多个线程之间的协作,确保某个线程在另一个线程执行完成后再继续执行。
    • 如果在join()方法中指定了超时时间,那么当前线程将等待指定的时间,如果超时仍未完成,则继续执行。
  2. yield()

    • yield()方法是线程的静态方法,它让出当前线程的执行权,将其暂停,以便其他具有相同或更高优先级的线程可以执行。
    • yield()的作用是提高线程的执行效率和响应性。
    • 当一个线程调用yield()方法后,它会从运行状态转变为就绪状态,让出CPU执行权,然后和其他具有相同或更高优先级的线程竞争CPU资源。
    • 注意,yield()方法并不能保证使得当前线程暂停执行,它只是提供一个提示给线程调度器,告知可以进行线程切换。

需要注意的是,join()方法可以用于线程的协作,而yield()方法用于线程的调度。join()方法会阻塞线程直到目标线程执行完成,而yield()方法会主动让出CPU执行权,使得其他线程有机会执行。

总结:

        本文我们介绍了使用线程的三种方法以及线程类中的常见成员方法,多线程是处理高并发问题的一个重要手段,因此我们一定要学好多线程。

如果我的内容对你有帮助,请点赞,评论,收藏。创作不易,大家的支持就是我坚持下去的动力!

 

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

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

相关文章

使用贝叶斯滤波器通过运动模型和嘈杂的墙壁传感器定位机器人研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

微服务系列<3>---微服务的调用组件 rpc 远程调用

什么是rpc调用,让我们调用远程方法就像调用本地方法一样 这就属于rpc调用 rpc是针对于本地来说的 调用远程方法根调用本地方法一样 如果能达到这种效果 就是rpc调用如果达到一种效果 调用远程和调用本地一样 他就是一种rpc框架2个微服务 之间发的调用 我们之前通过ribbon的方式…

云原生落地实践的25个步骤

一、什么是云原生&#xff1f; 云原生从字面意思上来看可以分成云和原生两个部分。 云是和本地相对的&#xff0c;传统的应用必须跑在本地服务器上&#xff0c;现在流行的应用都跑在云端&#xff0c;云包含了IaaS,、PaaS和SaaS。 原生就是土生土长的意思&#xff0c;我们在开始…

数论分块学习笔记

准备开始复习莫比乌斯反演&#xff0c;杜教筛这一部分&#xff0c;先复习一下数论分块 0.随便说说 数论分块可以计算如下形式的式子 ∑ i 1 n f ( i ) g ( ⌊ n i ⌋ ) \sum_{i1}^{n}f(i)g(\lfloor\frac{n}{i}\rfloor) ∑i1n​f(i)g(⌊in​⌋)。 利用的原理是 ⌊ n i ⌋ \lf…

UE虚幻引擎 UTextBlock UMG文本控件超过边界区域以后显示省略号

版本 5.2.1 裁剪 - 剪切 - 剪切到边界 裁剪 - 高级 - 溢出策略 - 省略

消息队列项目(1)

概念 这里的消息队列, 大致上就是一个生产者消费者模型. 我这个消息队列是仿照 RabbitMQ 的实现原理来进行编写的 需求分析 有几个核心的概念: 生产者(Producer)消费者(Consumer)中间人(Broker)发布(Publish) :生产者向中间人投递消息的过程订阅(Subcribe) :记录哪些消费者…

【腾讯云 Cloud Studio 实战训练营】CloudStudio体验真正的现代化开发方式,双手插兜不知道什么叫对手!

CloudStudio体验真正的现代化开发方式&#xff0c;双手插兜不知道什么叫对手&#xff01; 文章目录 CloudStudio体验真正的现代化开发方式&#xff0c;双手插兜不知道什么叫对手&#xff01;前言出现的背景一、CloudStudio 是什么&#xff1f;二、CloudStudio 的特点三、CloudS…

【LeetCode每日一题】——766.托普利茨矩阵

文章目录 一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【题目提示】七【题目进阶】八【解题思路】九【时间频度】十【代码实现】十一【提交结果】 一【题目类别】 矩阵 二【题目难度】 简单 三【题目编号】 766.托普利茨矩阵 四【题目描述…

【雕爷学编程】MicroPython动手做(30)——物联网之Blynk 2

知识点&#xff1a;什么是掌控板&#xff1f; 掌控板是一块普及STEAM创客教育、人工智能教育、机器人编程教育的开源智能硬件。它集成ESP-32高性能双核芯片&#xff0c;支持WiFi和蓝牙双模通信&#xff0c;可作为物联网节点&#xff0c;实现物联网应用。同时掌控板上集成了OLED…

FPGA项目设计:数字时钟

项目要求&#xff1a; 设计一个数字时钟&#xff0c;数码管前两位显示小时&#xff0c;数码管中间两位显示分钟&#xff0c;数码管后面两位显示秒。 项目设计&#xff1a; 系统框架图&#xff1a; 计数模块时序图&#xff1a; 代码实现&#xff1a; 计数模块&#xff1a; /…

通向架构师的道路之apache_tomcat_https应用

一、总结前一天的学习 通过上一章我们知道、了解并掌握了Web Server结合App Server是怎么样的一种架构&#xff0c;并且亲手通过Apache的Http Server与Tomcat6进行了整合的实验。 这样的架构的好处在于&#xff1a; 减轻App Server端的压力&#xff0c;用Web Server来分压…

Linux下基于Dockerfile构建镜像应用(1)

目录 基于已有容器创建镜像 Dockerfile构建SSHD镜像 构建镜像 测试容器 可以登陆 Dockerfile构建httpd镜像 构建镜像 测试容器 Dockerfile构建nginx镜像 构建镜像 概述&#xff1a; Docker 镜像是Docker容器技术中的核心&#xff0c;也是应用打包构建发布的标准格式。…

计算机视觉与图形学-神经渲染专题-ConsistentNeRF

摘要 Neural Radiance Fields (NeRF) 已通过密集视图图像展示了卓越的 3D 重建能力。然而&#xff0c;在稀疏视图设置下&#xff0c;其性能显着恶化。我们观察到&#xff0c;在这种情况下&#xff0c;学习不同视图之间像素的 3D 一致性对于提高重建质量至关重要。在本文中&…

在linux上面部署activemq

1、下载 网址&#xff1a;ActiveMQ 注意&#xff1a;新版本5.17起 要求jdk11, 5.16兼容jdk8, 所以&#xff0c;确保已经安装 java11 或以上的版本 这里安装较新版&#xff1a;5.18.2&#xff0c;已经安装了java17 如何安装jdk17,请详见我的另一篇文章&#xff1a;linux…

Git分布式版本控制工具和GitHub(一)--简介

一.Git概述 1.Git简介 【1】什么是Git? Git就是代码版本管理工具。 【2】为什么要使用Git &#xff08;1&#xff09;版本控制 写代码就是不断写BUG的过程&#xff08;当然我们是不会这么说的&#xff09;&#xff0c;很多时候你写了100行代码之后&#xff0c;突然醒悟&…

Python高阶技巧 设计模式

设计模式 设计模式是一种编程套路&#xff0c;可以极大的方便程序的开发。 最常见、最经典的设计模式&#xff0c;就是我们所学习的面向对象了。 除了面向对象外&#xff0c;在编程中也有很多既定的套路可以方便开发&#xff0c;我们称之为设计模式&#xff1a; 单例、工厂…

windows系统之WSL 安装 Ubuntu

WSL windows10 以上才有这个wsl功能 WSL&#xff1a; windows Subsystem for Linux 是应用于Windows系统之上的Linux子系统 作用很简单&#xff0c;可以在Windows系统中获取Linux系统环境&#xff0c;并完全直连计算机硬件&#xff0c;无需要通过虚拟机虚拟硬件 Windows10的W…

41. linux通过yum安装postgresql

文章目录 1.下载安装包2.关闭内置PostgreSQL模块:3.安装postgresql服务:4.初始化postgresql数据库:5.设置开机自启动:6.启动postgresql数据库7.查看postgresql进程8.通过netstat命令或者lsof 监听默认端口54329.使用find命令查找了一下postgresql.conf的配置位置10.修改postgre…

DLA :pytorch添加算子

pytorch的C extension写法 这部分主要介绍如何在pytorch中添加自定义的算子(例如&#xff0c;您可能希望 使用您在论文中找到的新颖激活函数&#xff0c;或实现操作 您作为研究的一部分进行了开发。)&#xff0c;需要以下cuda基础。就总体的逻辑来说正向传播需要输入数据&#…

【消息中间件】原生PHP对接Uni H5、APP、微信小程序实时通讯消息服务

文章目录 视频演示效果前言一、分析二、全局注入MQTT连接1.引入库2.写入全局连接代码 二、PHP环境建立总结 视频演示效果 【uniapp】实现买定离手小游戏 前言 Mqtt不同环境问题太多&#xff0c;新手可以看下 《【MQTT】Esp32数据上传采集&#xff1a;最新mqtt插件&#xff08;支…