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

【线程】Java线程操作

【线程】Java线程操作

      • 一、启动线程
        • 1.1 run()和start()的区别
      • 二、终止线程
      • 三、等待线程
      • 四、线程的状态

一、启动线程

Java中通过start()方法来启动一个线程,其次我们要着重理解start()和run()的区别。

1.1 run()和start()的区别

我们通过一份代码来进行观察:

public class ThreadDemo1  {public static void main(String[] args) throws InterruptedException {Thread t=new Thread(()-> {while(true){System.out.println("hello 000");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}});//第一次运行start()t.start();//第二次运行run()//t.run()while (true){System.out.println("hello 111");Thread.sleep(1000);}}
}

在这里插入图片描述
从结果上来看,用start() 方法,两个线程都正常运行了(main线程和t线程);而使用run()方法,似乎只有一个线程在正常运行。
我们可以用Jconsole来查看一下:
在这里插入图片描述
可以发现,使用start()方法真正创建出了线程,而使用run()方法只是在main线程里执行t线程对象的逻辑,并没有真正创建线程。那么我们可以这样理解:** start()方法用于创建线程,系统在合适的时机调用run方法,run()方法用于执行线程内部的逻辑。**

二、终止线程

想要终止一个线程,其实是需要里外配合的。具体来说,比如我们想要在main线程内控制t线程,我们就需要在t线程中引入一个标志位,用来控制线程。同时,我们要能在main线程中能够控制这个标志位。接下来看示例:

  1. 手动设置标志位
public class ThreadDemo1  {private static boolean isQuit =false;public static void main(String[] args) throws InterruptedException {Thread t=new Thread(()-> {while(!isQuit){System.out.println("hello");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}});t.start();//这个时间需要大于t线程中的休眠时间//避免因线程的随机调度使得t线程还没启动,标志位就被更改Thread.sleep(2000);isQuit=true;}
}

运行结果:
在这里插入图片描述
这里还有一个小问题:
在这里插入图片描述
如果我们把isQuit(自定义的标志位)写到main方法内部作为一个局部变量,此时就会编译报错。
这是因为λ表达式在进行变量捕获时,对于外部定义的局部变量,要求是final或者是effectively final类型的。
在这里插入图片描述
那为什么写成成员变量就可以了呢,此时是走了另一条语法规则,λ表达式/内部类可以访问外部类的成员变量,这件事情不受λ表达式变量捕获的限制。

但是我们认为,这种手动设置标志位的方式不够优雅,Thread类呢,提供了一种更加优雅的方法:interrupt()

  1. 使用Thread类提供的interrupt方法
public class ThreadDemo1  {public static void main(String[] args) throws InterruptedException {Thread t=new Thread(()-> {while(!Thread.currentThread().isInterrupted()){System.out.println("hello");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}});t.start();//这个时间需要大于t线程中的休眠时间//避免因线程的随机调度使得t线程还没启动,标志位就被更改Thread.sleep(2000);t.interrupt();}
}
  • Thread.currentThread()用于获取当前线程的引用,如果是继承Thread,那么可以用this引用,但如果是实现Runnable或者是lambda表达式,就只能使用该方法来获取当前线程的引用。
    在这里插入图片描述
    此处出现了一个比较奇怪的错误 : 明明已经报错了,怎么还没停下来。
    这里其实是sleep搞的鬼。
    此处线程处于这种休眠状态,调用interrupt()就会提前唤醒这个线程。线程被提前唤醒,会做两件事:
    (1)抛出 InterruptedException异常,被catch捕获到;
    (2)清除Thread对象的标志位,把标志位继续设为false。
    所以此时线程没有真正停止。而想要使这个线程停止,只需要做出一点小小的改进:在catch中写入break:
try {Thread.sleep(1000);
} catch (InterruptedException e) {break;
}

此时思考一个问题,那么我手动设置标志位,为什么不会有这样的问题?
这是因为,手动设置的标志位并不是Thread对象的属性,只是当前类的一个成员变量。即使线程被提前唤醒,也是不能去改变这里手动设置的标志位的。

Java这里对于线程的终止采用的是一种“软性”操作,即需要线程配合才能终止。操作系统的API提供了强行终止线程的操作,但这件事往往弊大于利,Java中并没有引入这样的强制性方法。

三、等待线程

由于多个线程的执行顺序是不确定的(随机调度,抢占式执行),所以我们的有些目的就难以实现。但是我们可以通过某些api,来影响线程的执行顺序,比如可以让一个线程来等待另一个线程。

public class ThreadDemo1  {public static void main(String[] args) throws InterruptedException {Thread t=new Thread(()-> {for(int i=0;i<10;i++){System.out.println("hello");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException();}}});t.start();t.join();System.out.println("这是主线程,期望在t线程结束后打印");}
}

这里的语法是这样,在main线程中写入t.join(),就是让main线程等待t线程执行完毕再继续执行。
在这里插入图片描述
从系统调度的角度来说,这里就是让main线程主动放弃被系统调度的机会,直到 t 线程执行完,再恢复。
明确来讲,这里不是确定的“执行顺序”,而是确定的“结束顺序”。

在这里插入图片描述
join方法也可以设置一个时间,避免要等的线程内部设计出了死循环,而出现的“死等”。较为常用的就是这种join(long millis)

四、线程的状态

之前谈到进程有就绪和阻塞两种状态。使用Jconsole也可以观察到线程的状态
Java中,对线程的状态进行了进一步的细分:

状态对应的含义
NEWThread对象创建好了,但是还没有调用start方法在系统中创建线程。
TERMINATEDThread对象仍然存在,但是系统内部的线程已经执行完了
RUNNABLE就绪状态,表示这个线程正在CPU上执行,或者随时准备去CPU上执行
TIMED_WAITING指定时间的阻塞,到达一定时间后自动解除阻塞。例如:sleep()、join(long millis)
WAITING不带时间的阻塞(死等),必须满足一定的条件才解除阻塞
BLOCKED由于锁竞争,引起的阻塞

在这里插入图片描述
讲到这里,大部分的状态我们都见识过了。对于BLOCKED的状态,涉及到我们所要讲的线程安全问题,后面在详细论述。

相关文章:

【线程】Java线程操作

【线程】Java线程操作 一、启动线程1.1 run()和start()的区别 二、终止线程三、等待线程四、线程的状态 一、启动线程 Java中通过start()方法来启动一个线程&#xff0c;其次我们要着重理解start()和run()的区别。 1.1 run()和start()的区别 我们通过一份代码来进行观察&…...

Linux内核

Linux内核是Linux操作系统的核心部分&#xff0c;它管理着硬件资源并提供基本的服务给用户程序。以下是Linux内核的几个关键方面&#xff1a; 1. 架构&#xff1a; 单内核设计&#xff1a;Linux采用的是单内核设计&#xff0c;这意味着所有操作系统服务都在一个地址空间内运行…...

Sentinel服务保护

Sentinel是阿里巴巴开源的一款服务保护框架&#xff0c;目前已经加入SpringCloudAlibaba中。官方网站&#xff1a; home | Sentinel Sentinel 的使用可以分为两个部分: 核心库&#xff08;Jar包&#xff09;&#xff1a;不依赖任何框架/库&#xff0c;能够运行于 Java 8 及以…...

python代码制作数据集的测试和数据质量检测思路

前言 本文指的数据集为通用数据集&#xff0c;并不单是给机器学习领域使用。包含科研和工业领域需要自己制作数据集的。 首先&#xff0c;在制作大型数据集时&#xff0c;代码错误和数据问题可能会非常复杂。 前期逻辑总是简单的&#xff0c;库库一顿写&#xff0c;等排查的时…...

笔记记录 k8s-install

master节点安装: yum upgrade -y 更新系统 yum update -y 升级内核 ifconfig ens33 关闭swap swapoff -a (临时) vim /etc/fstab (永久) #/dev/mapper/cl-swap swap swap defaults 0 0 vim /etc/sysctl.conf vm.swappin…...

丹摩征文活动|基于丹摩算力的可图(Kolors)的部署与使用

Kolors是一个以生成图像为目标的人工智能系统&#xff0c;可能采用了类似于OpenAI的DALLE、MidJourney等文本生成图像的技术。通过自然语言处理&#xff08;NLP&#xff09;和计算机视觉&#xff08;CV&#xff09;相结合&#xff0c;Kolors能够根据用户提供的文本描述生成符合…...

【Vue】 npm install amap-js-api-loader指南

前言 项目中的地图模块突然打不开了 正文 版本太低了&#xff0c;而且Vue项目就应该正经走项目流程啊喂&#xff01; npm i amap/amap-jsapi-loader --save 官方说这样执行完&#xff0c;就这结束啦&#xff01;它结束了&#xff0c;我还没有&#xff0c;不然不可能记录这篇文…...

MacOS下的Opencv3.4.16的编译

前言 MacOS下编译opencv还是有点麻烦的。 1、Opencv3.4.16的下载 注意&#xff0c;我们使用的是Mac&#xff0c;所以ios pack并不能使用。 如何嫌官网上下载比较慢的话&#xff0c;可以考虑在csdn网站上下载&#xff0c;应该也是可以找到的。 2、cmake的下载 官网的链接&…...

Android中的依赖注入(DI)框架Hilt

Hilt 是 Android 提供的一种依赖注入&#xff08;DI&#xff09;框架&#xff0c;它基于 Dagger&#xff0c;目的是简化依赖注入的使用&#xff0c;提供更易用的接口和与 Android 生命周期组件的紧密集成。下面是 Hilt 的详细介绍。 为什么选择 Hilt? 依赖注入的优势&#xf…...

5.STM32之通信接口《精讲》之USART通信---实验串口接收程序

根据上节&#xff0c;我们一已经完成了串口发送程序的代码&#xff0c;并且深入的解析探索了串口的原理&#xff0c;接下来&#xff0c;Whappy小编将带领大家进入串口接收程序的探索与实验&#xff0c;并将结合上一节串口发送一起来完成串口的发送和接收实验。 上来两张图 上图…...

【Redis_Day6】Hash类型

【Redis_Day6】Hash类型 Hash类型操作hash的命令hset&#xff1a;设置hash中指定的字段&#xff08;field&#xff09;的值&#xff08;value&#xff09;hsetnx&#xff1a;想hash中添加字段并设置值hget&#xff1a;获取hash中指定字段的值hexists&#xff1a;判断hash中是否…...

[开源] SafeLine 好用的Web 应用防火墙(WAF)

SafeLine&#xff0c;中文名 “雷池”&#xff0c;是一款简单好用, 效果突出的 Web 应用防火墙(WAF)&#xff0c;可以保护 Web 服务不受黑客攻击 一、简介 雷池通过过滤和监控 Web 应用与互联网之间的 HTTP 流量来保护 Web 服务。可以保护 Web 服务免受 SQL 注入、XSS、 代码注…...

40分钟学 Go 语言高并发:Select多路复用

Select多路复用 学习目标 知识点掌握程度应用场景select实现原理深入理解底层机制channel通信和多路选择超时处理掌握超时控制方法避免阻塞和资源浪费优先级控制理解优先级实现处理多个channel的顺序性能考虑了解性能优化点高并发场景优化 1. Select实现原理 让我们通过一个…...

candence: 如何快速设置SUBCLASS 的颜色

如何快速设置SUBCLASS 的颜色 一、一般操作 正常情况下修改SUBCLASS&#xff0c;需要如下步骤进行设置&#xff1a; 二、快速操作 右键&#xff0c;选择一个颜色即可...

FinalShell进行前端项目部署及nginx配置

首先需要准备服务器(阿里云、腾讯云都可)与域名&#xff1b; 示例为阿里云服务器&#xff1b; 1.进行FinalShell下载 下载官网 https://www.hostbuf.com/ 2.下载完毕后 配置FinalShell ssh ​ 名称自定义即可&#xff01; 2-1 提示连接成功 ​ 3.首先检查nginx是否下载 …...

神经网络(系统性学习一):入门篇——简介、发展历程、应用领域、基本概念、超参数调优、网络类型分类

相关文章&#xff1a; 神经网络中常用的激活函数 神经网络简介 神经网络&#xff08;Neural Networks&#xff09;是受生物神经系统启发而设计的数学模型&#xff0c;用于模拟人类大脑处理信息的方式。它由大量的节点&#xff08;或称为“神经元”&#xff09;组成&#xff0…...

用nextjs开发时遇到的问题

这几天已经基本把node后端的接口全部写完了&#xff0c;在前端开发时考虑时博客视频类型&#xff0c;考虑了ssr&#xff0c;于是选用了nextJs&#xff0c;用的是nextUi,tailwincss,目前碰到两个比较难受的事情。 1.nextUI个别组件无法在服务器段渲染 目前简单的解决方法&…...

微前端基础知识入门篇(二)

概述 在上一篇介绍了一些微前端的基础知识,详见微前端基础知识入门篇(一)。本文主要介绍qiankun微前端框架的实战入门内容。 qiankun微前端实践 通过Vite脚手架分别创建三个程序,主应用A为:vite+vue3+ts,两个微应用分别为B:vite+vue3+ts;C:vite+React+ts。因为qiankun的…...

自然语言处理:第六十五章 MinerU 开源PDF文档解析方案

本人项目地址大全&#xff1a;Victor94-king/NLP__ManVictor: CSDN of ManVictor 原文地址&#xff1a;MinerU&#xff1a;精准解析PDF文档的开源解决方案 论文链接&#xff1a;MinerU: An Open-Source Solution for Precise Document Content Extraction git地址&#xff1…...

Arcpy 多线程批量重采样脚本

Arcpy 多线程批量重采样脚本 import arcpy import os import multiprocessingdef resample_tifs(input_folder, output_folder, cell_size0.05, resampling_type"BILINEAR"):"""将指定文件夹下的所有 TIFF 文件重采样到指定分辨率&#xff0c;并输出…...

基于2D工程图几何特征与梯度提升模型的制造成本智能预测

1. 项目概述&#xff1a;从图纸到报价的智能革命在制造业&#xff0c;尤其是像汽车零部件这样的离散制造领域&#xff0c;报价速度直接决定了订单的生死。传统上&#xff0c;拿到一张新的2D工程图&#xff08;DWG格式&#xff09;&#xff0c;成本工程师需要花上几天甚至几周时…...

用STM32CubeMX和HAL库快速上手WS2812B:告别手动计算延时,一键生成驱动框架

基于STM32CubeMX的WS2812B智能灯光控制&#xff1a;从零构建现代化驱动方案在智能硬件和物联网设备快速发展的今天&#xff0c;WS2812B可编程LED灯带因其丰富的色彩表现和简单的单线控制方式&#xff0c;成为创客和工程师们最喜爱的显示组件之一。然而&#xff0c;传统的寄存器…...

Scroll Reverser:让Mac的多设备滚动体验回归直觉的免费神器

Scroll Reverser&#xff1a;让Mac的多设备滚动体验回归直觉的免费神器 【免费下载链接】Scroll-Reverser Per-device scrolling prefs on macOS. 项目地址: https://gitcode.com/gh_mirrors/sc/Scroll-Reverser 你是否曾经在MacBook的触控板和鼠标之间切换时&#xff0…...

【MySQL数据库 | 第一篇】 概述

数据库相关概念&#xff1a; 数据库(Database)&#xff1a;数据库是指一组有组织的数据的集合&#xff0c;通过计算机程序进行管理和访问。数据库管理系统&#xff1a;操纵和管理数据库的大型软件SQL&#xff1a;操作关系型数据库的编程语言&#xff0c;定义了一套操作关系型数…...

OpenCore Legacy Patcher完全指南:3步让旧款Mac焕发新生的终极方案

OpenCore Legacy Patcher完全指南&#xff1a;3步让旧款Mac焕发新生的终极方案 【免费下载链接】OpenCore-Legacy-Patcher Experience macOS just like before 项目地址: https://gitcode.com/GitHub_Trending/op/OpenCore-Legacy-Patcher 你是否拥有一台性能尚可但已被…...

告别鼠标点击,微博图片批量下载的轻松方案

告别鼠标点击&#xff0c;微博图片批量下载的轻松方案 【免费下载链接】weiboPicDownloader Download weibo images without logging-in 项目地址: https://gitcode.com/gh_mirrors/we/weiboPicDownloader 还记得那个周末的下午吗&#xff1f;你喜欢的博主发布了九宫格美…...

从无线破解到PDF解密:盘点那些容易被忽略的‘非主流’密码审计场景与工具

密码安全审计的隐秘战场&#xff1a;从无线网络到加密文档的实战指南 当大多数人谈论密码安全时&#xff0c;脑海中浮现的往往是服务器登录、数据库访问这些企业级场景。然而在数字生活的每个角落&#xff0c;从家庭Wi-Fi到工作文档&#xff0c;密码保护的脆弱性同样可能成为安…...

从数据到模型:手把手教你预处理MPIIFaceGaze和EyeDiap数据集(Python实战)

从数据到模型&#xff1a;手把手教你预处理MPIIFaceGaze和EyeDiap数据集&#xff08;Python实战&#xff09;当你第一次打开MPIIFaceGaze或EyeDiap数据集的压缩包时&#xff0c;那种面对杂乱文件夹和神秘.mat文件的迷茫感&#xff0c;我太熟悉了。作为计算机视觉工程师&#xf…...

Lovable内部工具开发方法论(从需求黑洞到用户自发推广的完整闭环)

更多请点击&#xff1a; https://kaifayun.com 第一章&#xff1a;Lovable内部工具开发方法论&#xff08;从需求黑洞到用户自发推广的完整闭环&#xff09; Lovable 方法论的核心不是交付功能&#xff0c;而是培育“工具依赖感”——当一线工程师在凌晨三点调试线上问题时&am…...

英雄联盟回放播放难题终极解决方案:ROFLPlayer完整使用指南

英雄联盟回放播放难题终极解决方案&#xff1a;ROFLPlayer完整使用指南 【免费下载链接】ROFL-Player (No longer supported) One stop shop utility for viewing League of Legends replays! 项目地址: https://gitcode.com/gh_mirrors/ro/ROFL-Player 还在为英雄联盟旧…...