当前位置: 首页 > 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获取…...

基于算法竞赛的c++编程(28)结构体的进阶应用

结构体的嵌套与复杂数据组织 在C中&#xff0c;结构体可以嵌套使用&#xff0c;形成更复杂的数据结构。例如&#xff0c;可以通过嵌套结构体描述多层级数据关系&#xff1a; struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...

Python爬虫实战:研究MechanicalSoup库相关技术

一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...

Prompt Tuning、P-Tuning、Prefix Tuning的区别

一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...

Zustand 状态管理库:极简而强大的解决方案

Zustand 是一个轻量级、快速和可扩展的状态管理库&#xff0c;特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...

PHP和Node.js哪个更爽?

先说结论&#xff0c;rust完胜。 php&#xff1a;laravel&#xff0c;swoole&#xff0c;webman&#xff0c;最开始在苏宁的时候写了几年php&#xff0c;当时觉得php真的是世界上最好的语言&#xff0c;因为当初活在舒适圈里&#xff0c;不愿意跳出来&#xff0c;就好比当初活在…...

IP如何挑?2025年海外专线IP如何购买?

你花了时间和预算买了IP&#xff0c;结果IP质量不佳&#xff0c;项目效率低下不说&#xff0c;还可能带来莫名的网络问题&#xff0c;是不是太闹心了&#xff1f;尤其是在面对海外专线IP时&#xff0c;到底怎么才能买到适合自己的呢&#xff1f;所以&#xff0c;挑IP绝对是个技…...

uniapp 小程序 学习(一)

利用Hbuilder 创建项目 运行到内置浏览器看效果 下载微信小程序 安装到Hbuilder 下载地址 &#xff1a;开发者工具默认安装 设置服务端口号 在Hbuilder中设置微信小程序 配置 找到运行设置&#xff0c;将微信开发者工具放入到Hbuilder中&#xff0c; 打开后出现 如下 bug 解…...

uniapp 实现腾讯云IM群文件上传下载功能

UniApp 集成腾讯云IM实现群文件上传下载功能全攻略 一、功能背景与技术选型 在团队协作场景中&#xff0c;群文件共享是核心需求之一。本文将介绍如何基于腾讯云IMCOS&#xff0c;在uniapp中实现&#xff1a; 群内文件上传/下载文件元数据管理下载进度追踪跨平台文件预览 二…...

git: early EOF

macOS报错&#xff1a; Initialized empty Git repository in /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/.git/ remote: Enumerating objects: 2691797, done. remote: Counting objects: 100% (1760/1760), done. remote: Compressing objects: 100% (636/636…...

深入浅出WebGL:在浏览器中解锁3D世界的魔法钥匙

WebGL&#xff1a;在浏览器中解锁3D世界的魔法钥匙 引言&#xff1a;网页的边界正在消失 在数字化浪潮的推动下&#xff0c;网页早已不再是静态信息的展示窗口。如今&#xff0c;我们可以在浏览器中体验逼真的3D游戏、交互式数据可视化、虚拟实验室&#xff0c;甚至沉浸式的V…...