当前位置: 首页 > news >正文

Java多线程 | 操作线程的方法详解

文章目录

    • 一、线程的启动
      • 1.1 start()方法
    • 二、线程的休眠与中断
      • 2.1 Thread.sleep()方法
      • 2.2 interrupt()方法
    • 三、线程的等待与唤醒
      • 3.1 wait()方法
      • 3.2 Object类的notify()和notifyAll()方法
      • 3.3 await()和signal()方法
      • 3.4 使用join()方法等待线程执行完成
    • 四、线程的状态控制与管理
      • 4.1 线程的优先级设置
      • 4.2 线程的守护与非守护状态
    • 五、其他常用的线程操作方法
      • 5.1 使用yield()方法让出CPU资源
      • 5.2 使用isAlive()方法判断线程是否存活

一、线程的启动

1.1 start()方法

  无论是通过继承Thread类还是实现Runnable接口,线程的启动都需要调用start()方法。

// 定义一个实现Runnable接口的自定义线程类
public class MyRunnable implements Runnable {@Overridepublic void run() {// 线程执行的代码逻辑}
}// 在主线程中创建并启动自定义线程
public class Main {public static void main(String[] args) {// 创建线程对象Thread thread = new Thread(new MyRunnable());// 启动线程thread.start();}
}

二、线程的休眠与中断

2.1 Thread.sleep()方法

Thread.sleep()方法用于使当前线程休眠一段时间。它接受一个以毫秒为单位的参数,表示线程休眠的时间,调用这个方法必须要声明或捕捉异常。

        try {// 线程休眠2秒Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("线程休眠结束");

2.2 interrupt()方法

  Thread类的interrupt()方法用于中断线程。当一个线程被中断时,它的中断状态将被设置为true(默认是 flase),设置后不一定真的中断,看jvm如何选择,我们把握不了。

  调用中断方法也要声明或捕捉异常:InterruptedException

  可以通过Thread类的isInterrupted()方法来检查线程的中断状态。

public class MyThread implements Runnable {@Overridepublic void run() {while (!Thread.currentThread().isInterrupted()) {System.out.println("线程执行中");}System.out.println("线程被中断");}
}public class Main {public static void main(String[] args) {// 创建线程对象Thread thread = new Thread(new MyThread());// 启动线程thread.start();// 中断子线程try {thread.interrupt();} catch (InterruptedException e) {e.printStackTrace();}}
}

三、线程的等待与唤醒

  线程的等待与唤醒是多线程编程中常用的一种机制,它允许线程在满足特定条件之前等待,然后在条件满足时被唤醒继续执行。Java提供了多种方式来实现线程的等待与唤醒。

3.1 wait()方法

  Object类中的wait()方法用于使当前线程等待,并释放当前线程持有的锁。wait()方法需要在synchronized块内部调用,以确保线程在等待前释放锁。

  调用wait方法使线程进入等到状态后,不会自动醒过来,需要手动让线程苏醒。

public class MyThread implements Runnable {final Object lock = new Object(); // 用于同步的对象@Overridepublic void run() {synchronized (lock) {// 线程等待,并释放锁lock.wait();}}
}

3.2 Object类的notify()和notifyAll()方法

  Object类中的notify()方法用于唤醒在相同对象上调用wait()方法而等待的单个线程,而notifyAll()方法用于唤醒所有在相同对象上调用wait()方法而等待的线程。

public class MyThread implements Runnable {private final Object lock;public MyThread(Object lock) {this.lock = lock;}@Overridepublic void run() {synchronized (lock) {try {// 线程等待,并释放锁lock.wait();// 线程被唤醒后执行其他操作System.out.println("线程被唤醒");} catch (InterruptedException e) {e.printStackTrace();}}}
}public class Main {public static void main(String[] args) {Object lock = new Object();// 创建自定义线程对象MyThread myThread1 = new MyThread(lock);MyThread myThread2 = new MyThread(lock);// 创建线程对象Thread thread1 = new Thread(myThread1);Thread thread2 = new Thread(myThread2);// 启动线程thread1.start();thread2.start();// 主线程休眠1秒后唤醒所有子线程try {Thread.sleep(1000);synchronized (lock) {lock.notifyAll();}} catch (InterruptedException e) {e.printStackTrace();}}
}

3.3 await()和signal()方法

  Condition接口的await()方法可以使线程等待,并释放当前线程持有的锁。当其他线程调用signal()或signalAll()方法时,等待的线程将被唤醒。

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class MyThread implements Runnable {private final Lock lock;private final Condition condition;public MyThread(Lock lock, Condition condition) {this.lock = lock;this.condition = condition;}@Overridepublic void run() {lock.lock();try {// 线程等待,并释放锁condition.await();// 线程被唤醒后执行其他操作System.out.println("线程被唤醒");} catch (InterruptedException e) {e.printStackTrace();} finally {lock.unlock();}}
}public class Main {public static void main(String[] args) {Lock lock = new ReentrantLock();Condition condition = lock.newCondition();// 创建自定义线程对象MyThread myThread = new MyThread(lock, condition);// 创建线程对象Thread thread = new Thread(myThread);// 启动线程thread.start();// 主线程休眠1秒后唤醒子线程try {Thread.sleep(1000);lock.lock();condition.signalAll();lock.unlock();} catch (InterruptedException e) {e.printStackTrace();}}
}

3.4 使用join()方法等待线程执行完成

  join()方法可以使一个线程等待另一个线程执行完成。当调用线程的join()方法时,调用线程将被阻塞,直到被调用的线程执行完成。下面是使用join()方法等待线程执行完成的示例:

public class MyThread implements Runnable {@Overridepublic void run() {System.out.println("子线程开始执行");try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("子线程执行完成");}
}public class Main {public static void main(String[] args) {// 创建自定义线程对象MyThread myThread = new MyThread();// 创建线程对象Thread thread = new Thread(myThread);// 启动线程thread.start();// 主线程调用join()方法等待子线程执行完成try {thread.join();} catch (InterruptedException e) {e.printStackTrace();}System.out.println("主线程继续执行");}
}

四、线程的状态控制与管理

4.1 线程的优先级设置

  线程的优先级用于指定线程在竞争CPU资源时的相对重要性。Java中使用整数表示线程的优先级,范围从1到10,其中1为最低优先级,10为最高优先级。可以使用setPriority()方法设置线程的优先级,使用getPriority()方法获取线程的优先级。

  注意:设置了高的优先级只是让线程获取资源的概率增大。

public class Main {public static void main(String[] args) {// 创建线程对象Thread thread = new Thread(() -> {System.out.println("线程执行中");});// 设置线程优先级为最高thread.setPriority(Thread.MAX_PRIORITY);// 获取线程优先级int priority = thread.getPriority();System.out.println("线程优先级:" + priority);// 启动线程thread.start();}
}

4.2 线程的守护与非守护状态

  线程可以分为守护线程和非守护线程。当只剩下守护线程运行时,JVM会退出。可以使用setDaemon()方法将线程设置为守护线程,使用isDaemon()方法判断线程是否为守护线程。

  守护线程的优先级低,这是因为守护线程的业务是不紧急的,像JVM垃圾回收线程就被设置成了守护线程。

public class Main {public static void main(String[] args) {// 创建线程对象Thread thread = new Thread(() -> {System.out.println("线程执行中");});// 设置线程为守护线程thread.setDaemon(true);// 判断线程是否为守护线程boolean isDaemon = thread.isDaemon();System.out.println("线程是否为守护线程:" + isDaemon);// 启动线程thread.start();}
}

五、其他常用的线程操作方法

5.1 使用yield()方法让出CPU资源

  yield()方法是一个静态方法,用于提示线程调度器将当前线程让出CPU资源,使得其他具有相同优先级的线程有机会执行。调用yield()方法后,当前线程会从运行状态变为就绪状态,然后等待线程调度器重新调度。

public class Main {public static void main(String[] args) {// 创建线程对象Thread thread1 = new Thread(() -> {for (int i = 0; i < 5; i++) {System.out.println("线程1执行中");Thread.yield();}});Thread thread2 = new Thread(() -> {for (int i = 0; i < 5; i++) {System.out.println("线程2执行中");Thread.yield();}});// 启动线程thread1.start();thread2.start();}
}

  在上面的示例中,创建了两个线程对象thread1thread2,它们分别输出"线程1执行中"和"线程2执行中"。在每次循环中,通过调用yield()方法让出CPU资源,使得两个线程可以交替执行。

5.2 使用isAlive()方法判断线程是否存活

  isAlive()方法用于判断线程是否存活,即线程是否已经启动且尚未终止。如果线程存活返回true,否则返回false

public class Main {public static void main(String[] args) {// 创建线程对象Thread thread = new Thread(() -> {System.out.println("线程执行中");});// 启动线程thread.start();// 判断线程是否存活boolean isAlive = thread.isAlive();System.out.println("线程是否存活:" + isAlive);}
}

相关文章:

Java多线程 | 操作线程的方法详解

文章目录 一、线程的启动1.1 start()方法 二、线程的休眠与中断2.1 Thread.sleep()方法2.2 interrupt()方法 三、线程的等待与唤醒3.1 wait()方法3.2 Object类的notify()和notifyAll()方法3.3 await()和signal()方法3.4 使用join()方法等待线程执行完成 四、线程的状态控制与管…...

【ConcurrentHashMap1.7源码】十分钟带你深入ConcurrentHashMap并发解析

ConcurrentHashMap1.7源码 四个核心要点 初始化PUT扩容GET Unsafe 初始化 五个构造方法 /*** Creates a new, empty map with the default initial table size (16).*/public ConcurrentHashMap() {}/*** Creates a new, empty map with an initial table size* accommodati…...

程序框架-事件中心模块-观察者模式

一、观察者模式 1.1 观察者模式定义 意图&#xff1a; 定义对象间的一种一对多的依赖关系&#xff0c;当一个对象的状态发生改变是&#xff0c;所有依赖于它的对象都能得到通知并自动更新。 适用性&#xff1a; 当一个对象状态的改变需要改变其他对象&#xff0c; 或实际对…...

通过AOP的ProceedingJoinPoint获取方法信息

文章目录 ProceedingJoinPoint用法 ProceedingJoinPoint用法 获得切点对应的方法&#xff08;Method&#xff09; 本处Method指的是java.lang.reflect.Method 若切入点表达式是方法&#xff0c;则获得的是切入点方法的信息。若切入点表达式是注解&#xff0c;则获得的是使用了…...

【JavaSE】初步认识类和对象

【本节目标】 1. 掌握类的定义方式以及对象的实例化 2. 掌握类中的成员变量和成员方法的使用 3. 掌握对象的整个初始化过程 目录 1. 面向对象的初步认知 2. 类定义和使用 3. 类的实例化 4. this引用 1. 面向对象的初步认知 1.1 什么是面向对象 Java是一门纯面向对象的语…...

python中的matplotlib画饼图(数据分析与可视化)

直接开始 1、先安装pandas和matplotlib pip install pandas pip install matplotlib2、然后在py文件中导入 import pandas as pd import matplotlib.pyplot as plt3、然后直接写代码 import pandas as pd import matplotlib.pyplot as pltpd.set_option("max_columns&…...

用Rust实现23种设计模式之 职责链模式

关注我&#xff0c;学习Rust不迷路&#xff01;&#xff01; 优点 解耦&#xff1a;职责链模式将请求发送者和接收者解耦&#xff0c;使得多个对象都有机会处理请求&#xff0c;而不是将请求的发送者和接收者紧密耦合在一起。灵活性&#xff1a;可以动态地改变或扩展处理请求…...

进销存管理中的技术创新和数字化转型

在进销存管理中&#xff0c;技术创新和数字化转型可以通过以下具体的应用案例来实现&#xff1a; 自动化仓储系统&#xff1a;利用自动化技术和机器人系统来管理仓库操作&#xff0c;包括货物的装卸、分拣和存储。这可以提高仓库的运作效率&#xff0c;减少人力成本&#xff0…...

与“云”共舞,联想凌拓的新科技与新突破

伴随着数字经济的高速发展&#xff0c;IT信息技术在数字中国建设中起到的驱动和支撑作用也愈发凸显。特别是2023年人工智能和ChatGPT在全球的持续火爆&#xff0c;更是为整个IT产业注入了澎湃动力。那么面对日新月异的IT信息技术&#xff0c;再结合疫情之后截然不同的经济环境和…...

【超细节】Vue3组件事件怎么声明,defineEmits与emit

目录 前言 一、基本语法 1. 子组件触发 2. 父组件监听 二、 事件参数 1. 传值 2. 接收值 三、 事件校验 四、注意事项 前言 组件事件是 Vue 组件之间进行通信的一种方式。它允许一个组件触发一个自定义事件&#xff0c;并且其他组件可以监听并响应这个事件。 一、基本…...

java Selenium 实现简单的网页操作

官方文档&#xff1a;入门指南 | Selenium Selenium是一个用于Web应用测试的工具。Selenium测试直接运行在浏览器中&#xff0c;就像真正的用户在操作一样。 所以使用这个前端测试话工具&#xff0c;可以自动化做很多事情&#xff0c;比如自动化抓取网页内容&#xff0c;俗称网…...

(数据库系统概论|王珊)第一章绪论-第一节:数据库系统概论

目录 一&#xff1a;四大基本概念 &#xff08;1&#xff09;数据(Data) &#xff08;2&#xff09;数据库(DataBase,DB) &#xff08;3&#xff09;数据库管理系统(DataBase Management System,DBMS) &#xff08;4&#xff09;数据库系统(Database System&#xff0c;DBS…...

深入理解TCP三次握手:连接可靠性与安全风险

目录 导言TCP简介和工作原理的回顾TCP三次握手的目的和步骤TCP三次握手过程中可能出现的问题和安全风险为什么TCP三次握手是必要的&#xff1f;是否可以增加或减少三次握手的次数&#xff1f;TCP四次挥手与三次握手的异同点 导言 在网络通信中&#xff0c;TCP&#xff08;Tra…...

基于人工智能的智能矿山解决方案

什么是智能矿山&#xff1f; 智能矿山是一种运用先进技术和智能化系统来管理和监控矿山运营的概念。它利用传感器、无线通信、数据分析和人工智能等技术&#xff0c;实现对矿山内部各个环节的实时监测、自动化控制和智能决策&#xff0c;从而提高矿山的效率、安全性和可持续性。…...

vue-cli3项目优化

首先添加两个量化的插件&#xff0c;方便对项目目前的情况进行分析&#xff1a; 1.添加speed-measure-webpack-plugin插件 —量化的指标可以看出前后对比 使用步骤&#xff1a; 安装speed-measure-webpack-plugin依赖 npm install speed-measure-webpack-plugin -D配置vue.c…...

Windows环境下VSCode安装PlatformIO Cero报错ERROR: HTTP error 403 while getting

安装PlatformIO插件成功&#xff0c;初始化失败 错误信息判断问题尝试访问https://pypi.tuna.tsinghua.edu.cn/simple/platformio/成功点击文件后报错如下&#xff1a; 解决问题- 换源 &#xff08; Windows下有两个地方需要更改&#xff09;cmd命令行Pip文件 总结&#xff1a;…...

git bash 安装sdkadmin

1.下载相关安装包,复制到git 安装目录 D:\software\Git\mingw64\bin 2. 运行 curl -s "https://get.sdkman.io" | bash...

如何在IEEE论文中添加伪代码pseudocode

前言 记录写论文过程中需要重复用的一些小技巧&#xff1a; 一、如何在IEEE论文中添加伪代码pseudocode pseudocode是经常需要在论文中使用的流程图&#xff0c;掌握如何写伪代码图是必须得。 1.引入库 代码如下&#xff08;示例&#xff09;&#xff1a; # 头部添加不可少的…...

【css】css隐藏元素

display:none&#xff1a;可以隐藏元素。该元素将被隐藏&#xff0c;并且页面将显示为好像该元素不在其中。visibility:hidden&#xff1a; 可以隐藏元素。但是&#xff0c;该元素仍将占用与之前相同的空间。元素将被隐藏&#xff0c;但仍会影响布局。 代码&#xff1a; <!…...

JUC并发编程(二)ForkJoinPool、Future、CompletableFuture、CAS

文章目录 ForkJoin分治工作窃取ForkJoinPool与ThreadPoolExecutor使用案例不带返回值的计算--RecursiveAction带返回值的计算--RecursiveTask Future 异步回调烧水案例join实现FutureTask实现 CompletableFuture为什么叫CompletableFuture?创建异步任务supplyAsyncrunAsync获取…...

三维GIS开发cesium智慧地铁教程(5)Cesium相机控制

一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点&#xff1a; 路径验证&#xff1a;确保相对路径.…...

Oracle查询表空间大小

1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...

Qt Widget类解析与代码注释

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码&#xff0c;写上注释 当然可以&#xff01;这段代码是 Qt …...

vue3 字体颜色设置的多种方式

在Vue 3中设置字体颜色可以通过多种方式实现&#xff0c;这取决于你是想在组件内部直接设置&#xff0c;还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法&#xff1a; 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...

MODBUS TCP转CANopen 技术赋能高效协同作业

在现代工业自动化领域&#xff0c;MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步&#xff0c;这两种通讯协议也正在被逐步融合&#xff0c;形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...

C++中string流知识详解和示例

一、概览与类体系 C 提供三种基于内存字符串的流&#xff0c;定义在 <sstream> 中&#xff1a; std::istringstream&#xff1a;输入流&#xff0c;从已有字符串中读取并解析。std::ostringstream&#xff1a;输出流&#xff0c;向内部缓冲区写入内容&#xff0c;最终取…...

用docker来安装部署freeswitch记录

今天刚才测试一个callcenter的项目&#xff0c;所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...

是否存在路径(FIFOBB算法)

题目描述 一个具有 n 个顶点e条边的无向图&#xff0c;该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序&#xff0c;确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数&#xff0c;分别表示n 和 e 的值&#xff08;1…...

智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制

在数字化浪潮席卷全球的今天&#xff0c;数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具&#xff0c;在大规模数据获取中发挥着关键作用。然而&#xff0c;传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时&#xff0c;常出现数据质…...

Device Mapper 机制

Device Mapper 机制详解 Device Mapper&#xff08;简称 DM&#xff09;是 Linux 内核中的一套通用块设备映射框架&#xff0c;为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程&#xff0c;并配以详细的…...