JavaEE 多线程第四节 (线程核心操作----线程开始/线程终止)

目录

1. start() 和 run() :

总结:

2. 线程的终止控制

例子

2. lambda表达式中的变量捕获

例子

3. 为什么需要“有效final”

总结


1. start()run()

  • start() 方法
    • 负责通知 JVM 和操作系统创建新线程。
    • 新线程被调度时,会调用 run() 方法,线程的任务会在新线程中运行。
    • 只能调用一次,重复调用会抛出 IllegalThreadStateException 异常。
Thread t = new Thread(() -> {System.out.println("Thread is running");
});// 正确的用法,启动新线程
t.start();  // 错误的用法,重新启动线程会抛出 IllegalThreadStateException
t.start();  // 抛出异常
  • run() 方法
    • 定义线程的实际执行内容,但不会创建新线程。
    • 如果直接调用 run(),它只是在当前线程中执行代码,而不创建新的执行线程
Thread t = new Thread(() -> {System.out.println("Thread is running");
});// 错误:这只是普通的方法调用,没有创建新线程
t.run();  // 直接在主线程执行,没有创建新的线程

总结:

  • start() 是启动线程的正确方法,它调用 run() 来执行任务,并通过底层系统 API 创建真正的操作系统级线程。
  • 不能在同一个线程对象上调用 start() 两次,否则会抛出 IllegalThreadStateException
  • run() 方法可以被直接调用,但它不会启动新线程,而是在当前线程执行任务。

2. 线程的终止控制

在Java中,主线程和子线程之间的协作是重要的。比如在一个子线程中运行一个无限循环,当某个条件满足时终止这个循环。常用的控制方式是通过一个共享变量,让主线程更新这个变量,然后子线程检查变量值来决定是否退出。

例子
public class Demo01 {private static boolean isQuit = false;public static void main(String[] args) throws InterruptedException {Thread t = new Thread(() -> {while (!isQuit) {System.out.println("hello thread");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}System.out.println("子线程结束");});t.start();// 主线程等待2秒后,将isQuit置为trueThread.sleep(2000);isQuit = true;System.out.println("主线程设置isQuit=true,通知子线程结束");}
}

在这个例子中,isQuit变量被主线程和子线程共享。主线程在2秒后将isQuit置为true,从而通知子线程结束循环。这种方法简单直接,但在多线程环境中需要确保isQuit变量的可见性(即使用volatile关键字或其他同步手段)。

2. lambda表达式中的变量捕获

在Java中,lambda表达式中引用的外部变量必须是**"有效final"**的(即变量的值在lambda表达式内部不能更改)。这个限制主要是因为lambda表达式会将变量“捕获”到内部类的作用域中去,而该变量必须是不可变的。

例子

在以下代码中,如果将共享变量isQuit直接放入lambda表达式中,必须确保其不可变或使用final修饰。

public class Demo02 {private static boolean isQuit = false;public static void main(String[] args) {Thread t = new Thread(() -> {while (!isQuit) {System.out.println("hello");}});t.start();}
}

如果在lambda表达式中修改了isQuit的值,则会报错,因为Java不允许在lambda中修改捕获的非final变量。

3. 为什么需要“有效final”

在Java的并发编程中,lambda表达式和匿名类具有闭包特性,这意味着它们可以引用外部作用域的变量,但变量必须是不可变的。这背后的原因包括以下几点:

  • 线程安全:不可变的变量在并发情况下是线程安全的。
  • 内存模型:Java的内存模型对线程间的变量可见性有严格要求,不可变变量可以保证不会被其他线程修改,从而简化了JVM的实现。

总结

  1. 使用isQuit控制线程的退出,主线程可以在某个时间点设置isQuittrue,从而通知子线程退出。
  2. lambda表达式中捕获外部变量时需要保证变量是不可变的,即有效final
  3. 使用volatile可以保证多线程环境中变量的可见性

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

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

相关文章

【Web.路由】——路由原理

这篇文章,我们来讲一讲什么是路由。 路由是 将用户请求地址映射为一个请求委托的过程,负责匹配传入的Http请求,然后将这些请求发送到应用的可执行终结点。 这里需要注意一个内容,发送到应用的可执行终结点。 路由的分类&#x…

大模型落地,要追求极致的务实主义

图源:AI生成 ▎****更快用上最新的大模型,是不是就赢定了? “能够像人类一样操作电脑。”这一堪称革命性的新技能来自10月23日Anthropic最新推出的升级版Claude 3.5 Sonnet模型,据介绍该模型不仅各项性能指标上取得显著提升&…

MobileNetV2实现实时口罩检测tensorflow

项目源码获取方式见文章末尾! 回复暗号:13,免费获取600多个深度学习项目资料,快来加入社群一起学习吧。 **《------往期经典推荐------》**项目名称 1.【Informer模型复现项目实战】 2.【卫星图像道路检测DeepLabV3Plus模型】 3.【…

机器学习 - 概述、数据集、Scikit-learn

目录 一、人工智能概述1、概念2、应用领域 二、机器学习1、概念2、数据集的构成3、算法分类a、监督学习b、无监督学习 4、开发流程5、可用数据集总结 三、Scikit-learn1、介绍2、安装3、数据集API介绍4、数据集返回值介绍5、数据集的划分6、数据集划分的API介绍7、案例a、获取鸢…

sass软件数据架构思路——未来之窗行业应用跨平台架构

一、SAAS多商户数据库 1.1 SaaS 多商户数据库的全部商户数据放在一个服务器上 1. 成本效益:集中管理和维护一个服务器通常比维护多个独立服务器更经济,降低硬件、运维和管理成本。 2. 数据集中管理:便于进行统一的数据备份、恢复和数据治理…

高清 MV 无字幕视频素材

在当下的短视频和自媒体时代,高清无字幕的视频素材无疑是创作者们的“得力助手”。不管是用于剪辑情感励志视频、制作搞笑段子,还是创作风景航拍视频,优质的素材库都能让你的创作如虎添翼。今天,我就为大家介绍几个海外的高质量素…

光学计算领域的突破:更快、更高效的光子存储单元

国际电气工程师团队首次开发出一种新的光子内存计算方法,这将在不久的将来使光学计算成为现实。 该团队包括来自匹兹堡大学斯旺森工程学院、加州大学圣巴巴拉分校、卡利亚里大学和东京工业大学(现东京科学大学)的研究人员。他们的研究成果发…

【论文阅读】Reliable, Adaptable, and Attributable Language Models with Retrieval

文章目录 OverviewCurrent Retrieval-Augmented LMsArchitectureTraining Limitations & Future Work Overview Parametic language models的缺点: 事实性错误的普遍存在验证的难度(可溯源性差)难以在有顾虑的情况下排除某些序列适应调整…

web pdf 图片拖动图片合成

web pdf 图片拖动图片合成 先看效果 前端 合成后 1.原理 以前写过相关的帖子,使用的是 canva 但是这次换了一个思路使用的是图片 1.先把pdf转成图片 2.把pdf图片和目标图片传到浏览器 3.原理就和图片合成一样了。见上一篇帖子 4.后端也一样只不过这次是将位置和pd…

LeetCode 107.二叉树的层次遍历 II

题目描述 给你二叉树的根节点 root ,返回其节点值 自底向上的层序遍历 。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历) 示例 1: 输入:root [3,9,20,null,null,15,7] 输出:[[1…

【力扣专题栏】两数相加,如何实现存储在链表中的整数相加?

题解目录 1、题目描述解释2、算法原理解析3、代码编写(原始版本)4、代码编写(优化版本) 1、题目描述解释 2、算法原理解析 3、代码编写(原始版本) /*** Definition for singly-linked list.* struct ListN…

快速上手机器学习-朴素贝叶斯

朴素贝叶斯 引言:本文通过介绍先验概率,后验概率,条件概率计算和贝叶斯定理等概率论内容引入朴素贝叶斯分类算法的基本思路,朴素贝叶斯的最终分类思想是将输入分类给概率最大的类,这也是概率模型算法的共有思想。本文专…

JVM(HotSpot):GC之G1垃圾回收器

文章目录 一、简介二、工作原理三、Young Collection 跨代引用四、大对象问题 一、简介 1、适用场景 同时注重吞吐量(Throughput)和低延迟(Low latency),默认的暂停目标是 200 ms超大堆内存,会将堆划分为…

第12次CCF CSP认证真题解

1、最小差值 题目链接&#xff1a;https://sim.csp.thusaac.com/contest/12/problem/0 100分代码&#xff1a; #include <iostream> #include <algorithm> using namespace std; int main(int argc, char *argv[]) {int n;cin >> n;int a[1010],b[1010];f…

【读书笔记·VLSI电路设计方法解密】问题28:什么是芯片可靠性

一块VLSI芯片不仅需要在前几天、几周或几个月内正常工作,还必须在整个使用寿命内可靠运行。任何用于商业目的的芯片的寿命通常定义为100,000小时或约11.4年。然而,在IC的设计、制造、组装和测试过程中,许多因素可能导致其早期失效。这一芯片开发方面被称为芯片可靠性。测试相…

LinkedList和链表之刷题课(下)

1. 给定x根据x把链表分割,大的结点放在x后面,小的结点放在x前面 题目解析: 注意此时的pHead就是head(头节点的意思) 基本上就是给定一个链表,我们根据x的值来把这个链表分成俩部分,大的那部分放在x后面,小的那部分放在x前面,并且我们不能改变链表本来的顺序,比如下面的链表,我…

【数据结构与算法】《Java 算法宝典:探秘从排序到回溯的奇妙世界》

目录 标题&#xff1a;《Java 算法宝典&#xff1a;探秘从排序到回溯的奇妙世界》一、排序算法1、冒泡排序2、选择排序3、插入排序4、快速排序5、归并排序 二、查找算法1、线性查找2、二分查找 三、递归算法四、动态规划五、图算法1. 深度优先搜索&#xff08;DFS&#xff09;2…

Ubuntu22.04环境搭建MQTT服务器

官网&#xff1a; https://mosquitto.org 1.引入库 sudo apt-add-repository ppa:mosquitto-dev/mosquitto-ppa2.升级安装工具 sudo apt-get update 3.安装 sudo apt-get install mosquitto 4.安装客户端 sudo apt-get install mosquitto-clients5.添加修改配置文件 进…

MySql数据库中数据类型

本篇将介绍在 MySql 中的所有数据类型&#xff0c;其中主要分为四类&#xff1a;数值类型、文本和二进制类型、时间日期、String 类型。如下&#xff08;图片来源&#xff1a;MySQL数据库&#xff09;&#xff1a; 目录如下&#xff1a; 目录 数值类型 1. 整数类型 2. …

Python | Leetcode Python题解之第516题最长回文子序列

题目&#xff1a; 题解&#xff1a; class Solution:def longestPalindromeSubseq(self, s: str) -> int:n len(s)dp [[0] * n for _ in range(n)]for i in range(n - 1, -1, -1):dp[i][i] 1for j in range(i 1, n):if s[i] s[j]:dp[i][j] dp[i 1][j - 1] 2else:dp…