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

JUC并发编程基础(包含线程概念,状态等具体实现)

一.JUC并发编程基础

1. 并行与并发

1.1 并发:

  1. 是在同一实体上的多个事件
  2. 是在一台处理器上"同时处理多个任务"
  3. 同一时刻,其实是只有一个事件在发生.

即多个线程抢占同一个资源.
在这里插入图片描述

1.2 并行

  1. 是在不同实体上的多个事件
  2. 是在多台处理器上同时处理多个任务
  3. 同一时刻,大家都在做事情.你做你的,我做我的.

即多个线程同时执行.

在这里插入图片描述

2. 进程,线程,管程

2.1 进程

在系统中运行的一个应用程序就是一个进程,每一个进程都有它自己的内存空间和系统资源.

2.2 线程

也被叫做轻量级进程,在同一个进程内会有1个或多个线程,是大多数操作系统进行时序调度的基本单元

2.3 管程

也被称为Monitor(监视器),也就是平时我们所说的锁.

3. 线程启动的三种方式

3.1 继承Thread类.重写run方法

继承重写

    public class MyThread extends Thread {@Overridepublic void run() {for (int i = 0; i < 100; i++) {System.out.println(Thread.currentThread().getName() + " " + i);}}}

执行

    public class ExtendThreadMain {public static void main(String[] args) {MyThread myThread = new MyThread();myThread.start();}}

注意:启动线程是调用父类的start方法,而不是直接去调用run方法.

3.2 实现Runable接口

实现重写

    public class MyThread implements Runnable{@Overridepublic void run() {for(int i=0;i<10;i++){System.out.println(Thread.currentThread().getName()+":"+i);}}}

主函数启动线程

    public class RunnableThreadMain {public static void main(String[] args) {MyThread myThread = new MyThread();Thread t1 = new Thread(myThread);t1.start();}}

当然我们还有另外一种写法

注意到Thread的构造方法的参数有
在这里插入图片描述

里面存在一个Runnable参数和一个线程名的两个参数的方法.熟悉静态内部类或者Lamba表达式的应该了解,这里完全可以利用这种特性来启动线程,所以我们可以这样改写.

public class RunnableThreadMain {public static void main(String[] args) {//        MyThread myThread = new MyThread();//        Thread t1 = new Thread(myThread);Thread t1 = new Thread(() -> {for (int i = 0; i < 10; i++) {System.out.println(Thread.currentThread().getName() + " " + i);}}, "t1");t1.start();}}

3.3 实现Callable接口

实现重写call方法(其实也就跟上述两个的run方法的作用一样)

    /*** 这里的泛型指的是call方法的返回值*/public class MyThread implements Callable<Integer> {@Overridepublic Integer call() throws Exception {int sum = 0;for (int i = 0; i < 100; i++) {sum+=i;}return sum;}}

主函数调度,这里与其他两种实现不同的是,可以有返回值,这里引用了FutureTask接口来接收这个值

    public class CallableThreadMain {public static void main(String[] args) throws ExecutionException, InterruptedException {MyThread myThread = new MyThread();FutureTask<Integer> futureTask = new FutureTask<>(myThread);Thread t1 = new Thread(futureTask);t1.start();Integer sum = futureTask.get();System.out.println("sum = " + sum);}}

注意:get方法时,方法会阻塞,直到这个线程执行完毕有返回值,代码才会往下进行.

4. 守护线程

守护线程

  • 守护线程是一种特殊的线程,它并不属于用户线程,也不受用户线程的控制,但它却有着特殊的重要性。
  • 守护线程的主要目的是为其他非守护线程提供服务。当所有的用户线程都结束时,守护线程也会随之结束
  • 守护线程的创建方式是在启动线程时调用Thread.setDaemon(true)方法,该方法将线程设置为守护线程。
  • 判断当前线程是否为守护线程调用 Thread.currentThread().isDaemon()方法,true为是,false为不是

守护线程的退出条件是:

  1. 所有用户线程都结束;
  2. 调用了Thread.stop()方法;
  3. 调用了Runtime.exit()方法。

注意:

  1. 守护线程只能有一个,一个JVM中只能有一个守护线程;
  2. 守护线程不能执行用户线程的run()方法,因为它没有用户线程可执行;
  3. 守护线程的优先级比较低,它只会在JVM中运行,不会影响到其他线程的运行;
  4. 守护线程的异常处理方式和非守护线程相同。
    public class ProtectThread {public static void main(String[] args) {//创建一个线程Thread t1 = new Thread(() -> {System.out.println(Thread.currentThread().getName() + ": " +(Thread.currentThread().isDaemon() ? " 守护线程" : "用户线程"));while (true) {}},"t1");t1.setDaemon(true);//设置为守护线程t1.start();System.out.println(Thread.currentThread().getName() + ": " +(Thread.currentThread().isDaemon() ? " 守护线程" : "主线程"));}}

5. windows,linux下查看和杀死进程

5.1windows

  • 任务管理器可以查看进程和线程数,也可以用来杀死进程.

  • tasklist 查看进程
    在这里插入图片描述

  • taskkill 杀死进程

    • 通常带两个参数 /F 强制杀死 /PID 进程id

5.2 linux

  • ps -ef 查看所有进程
    在这里插入图片描述

  • ps -fT -p 查看某个进程(PID)的所有线程

在这里插入图片描述

  • kill 杀死进程
  • top按大写H切换是否显示线程

动态展示所有进程占用cpu的情况
在这里插入图片描述

  • top -H -p 查看某个进程(PID)的所有线程

5.3 查看Java的进程

  • jps 命令查看所有 Java进程

  • jstack 查看某个Java进程 (PID) 的所有线程状态.
    在这里插入图片描述

  • jconsole 来查看某个Java进程中线程的运行情况(图形界面)
    在这里插入图片描述

6. 线程运行原理

我们知道JVM虚拟机中有栈和堆两块内存区域.

而每一个线程都有属于自己的栈区,每个线程直接的栈互不干扰,线程中每一个方法都是一个栈帧.

看如下这段代码的调度过程:
在这里插入图片描述

我们再通过一幅图来理解

在这里插入图片描述

7. 线程的上下文切换

有些时候由于一些原因,当线程在执行时,cpu被其他线程抢占到也就是说存在线程之间的切换的过程,我们称为上下文切换.

哪些原因会导致线程上下文切换呢

  • 线程的cpu时间片用完
  • 垃圾回收
  • 有更高优先级的线程需要运行
  • 线程自己调用了sleep,yield,wait,join,park,synchronized,lock等方法

当上下文切换时,需要由操作系统去保存当前线程的状态,也就是记录其中的一些变量啊,执行到哪一步啦,并恢复另一个线程的状态,Java中对应的概念就是程序计数器,它的作用是记住下一条JVM指令的执行地址,是线程自己私有的

  • 状态包括程序计数器,虚拟机栈中每个栈帧的信息,如局部变量,操作数栈,返回地址

注意:频繁的上下文切换会影响性能.

8. 线程的几种状态

8.1 五种(来源于操作系统)

在这里插入图片描述

  • 初始状态: 相当于我们刚刚new出来一个线程对象.仅是在语言层面创建了线程对象,还并未与操作系统线程相关联.
  • 可运行状态(就绪状态) : 指该线程已经被创建(与操作系统线程关联),可以由CPU调度执行.也就是都准备去抢占cpu啦,如果抢到了就会进入运行状态
  • 运行状态: 指获取了CPU时间片运行中的状态.
    • 当CPU时间片用完会从运行状态转换至就绪状态, 会导致线程的上下文切换
  • 阻塞状态
    • 如果调用了阻塞的API,例如BIO(同步阻塞IO)读写文件,这时该线程不会用到CPU,会导致线程上下文切换,进入阻塞状态.
    • 等BIO操作完毕,会由操作系统唤醒阻塞的线程,转换至可运行状态.
    • 与可运行状态的区别是,对阻塞状态的线程来说只要它们一直不唤醒,调度器一直不会考虑调度它们.

可以这样理解: 好比去上厕所,你抢到厕所的使用权啦,但是突然你又不想上啦,想起还有其他事情要做,总不能占着茅坑不拉屎叭,所以cpu,也就是厕所,你得离开这里,这个时候你去干其他的事都可以,等你忙完又想上厕所啦,这个时候又和别人一样需要有机会才能抢到厕所的使用权,也就是重新回到就绪状态.

  • 终止状态: 表示线程已经执行完毕,生命周期已经结束,不会在转换为其他状态.也就是代码执行完毕,没有循环的包裹,执行完就会进入终止状态.

8.2 六种(Java层面)

我们来查看Thread类当中的一个枚举类State
在这里插入图片描述
所以一共有六种状态,其具体为
在这里插入图片描述

  • NEW 线程刚被创建,但是还没有调用start()方法
  • RUNNABLE当调用了start()方法之后.

注意: JavaAPI层面的RUNNABLE状态涵盖了操作系统层面的可运行状态(就绪状态),运行状态,阻塞状态(由于BIO导致的线程阻塞,在Java里无法区别,仍然认为是可运行,也就是RUNNABLEZ状态)

  • BLOCKED 可以理解为抢占锁时未抢到,造成阻塞等待
  • WAITING 等待别的线程执行结束
  • TIMED_WATING 有时间的等待,也就是对应Thread.sleep();
  • TERMINATED 当线程代码运行结束
8.2.1 代码实现每种状态
  • NEW (创建线程不开始)
    在这里插入图片描述

  • RUNNABLE(就绪,运行,阻塞(操作系统的层面例如IO流时))
    在这里插入图片描述

  • TERMINATED (代码执行完毕就进入此状态)
    在这里插入图片描述

  • TIMED_WATING (睡眠时进入)
    在这里插入图片描述

  • WAITING(利用join方法,使线程2等待线程1执行完毕,此时状态为WAITING)
    在这里插入图片描述

  • BLOCKED(阻塞,抢占锁失败,阻塞等待)
    在这里插入图片描述

相关文章:

JUC并发编程基础(包含线程概念,状态等具体实现)

一.JUC并发编程基础 1. 并行与并发 1.1 并发: 是在同一实体上的多个事件是在一台处理器上"同时处理多个任务"同一时刻,其实是只有一个事件在发生. 即多个线程抢占同一个资源. 1.2 并行 是在不同实体上的多个事件是在多台处理器上同时处理多个任务同一时刻,大家…...

集中管理和分析日志:使用 ELK 套件构建强大的日志管理平台

集中管理和分析日志&#xff1a;使用 ELK 套件构建强大的日志管理平台 日志是监控和调试应用程序和系统的重要工具。集中管理和分析日志可以帮助你快速定位问题、了解系统运行状况和性能&#xff0c;并提高你的日志管理效率。ELK 是一个流行的日志管理解决方案&#xff0c;由 …...

深度学习 - 模型的保存与部署方式汇总

深度学习模型保存和加载格式科普 在深度学习中&#xff0c;模型的保存和加载是非常重要的环节。不同的格式有不同的特点和适用场景。本文将为新手朋友们介绍几种常见的模型格式&#xff0c;包括它们的简介、保存方式、加载方式、优缺点以及应用场景。 1. PyTorch (.pth, .pt)…...

人工智能对网络安全有何影响?

人工智能网络安全在短期、中期和长期如何变化 当今数字时代网络安全的重要性 在谈论人工智能在网络安全中的作用时&#xff0c;必须首先考虑短期影响&#xff0c;因为它们是最明显的&#xff0c;而且它是一个未知的领域&#xff0c;需要超越直接炒作的能力。 因此&#xff0…...

Oracle的RECYCLEBIN回收站:轻松恢复误删对象

目录 Oracle的RECYCLEBIN回收站&#xff1a;轻松恢复误删对象一、概念二、工作原理三、使用方法1 查看回收站中的对象2 恢复回收站中的对象2.1 恢复表&#xff08;TABLE&#xff09;2.2 恢复索引&#xff08;INDEX&#xff09;2.3 恢复视图&#xff08;VIEW&#xff09;2.4 恢复…...

Android 内存原理详解以及优化(二)

上一篇讲了内存原理&#xff0c;如果还没看可以先看上一篇&#xff1a;Android 内存原理详解以及优化&#xff08;一&#xff09; 这一篇我总结一下我们经常遇到的内存优化问题&#xff1a; 1.内存抖动 自定义view的ondraw是会被频繁调用的&#xff0c;那在这个方法里面就不能频…...

Shell学习——Shell变量

文章目录 Shell变量使用变量只读变量删除变量变量类型字符串变量&#xff1a; 在 Shell中&#xff0c;变量通常被视为字符串。整数变量&#xff1a; 在一些Shell中&#xff0c;你可以使用 declare 或 typeset 命令来声明整数变量。数组变量&#xff1a; Shell 也支持数组&#…...

Java中的持续集成与持续部署(CI/CD)

Java中的持续集成与持续部署&#xff08;CI/CD&#xff09; 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天我们将深入探讨Java中的持续集成&#xff08;Co…...

极狐GitLab 将亮相2024空天信息大会暨数字地球生态峰会,携手中科星图赋能空天行业开发者

GitLab 是一个全球知名的一体化 DevOps 平台&#xff0c;很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab &#xff1a;https://gitlab.cn/install?channelcontent&utm_sourcecsdn 是 GitLab 在中国的发行版&#xff0c;专门为中国程序员服务。可以一键式部署…...

Beats:使用 Filebeat 从 Python 应用程序中提取日志

本指南演示了如何从 Python 应用程序中提取日志并将其安全地传送到 Elasticsearch Service 部署中。你将设置 Filebeat 来监控具有标准 Elastic Common Schema (ECS) 格式字段的 JSON 结构日志文件&#xff0c;然后你将在 Kibana 中查看日志事件发生的实时可视化。虽然此示例使…...

51单片机第23步_定时器1工作在模式0(13位定时器)

重点学习51单片机定时器1工作在模式0的应用。 在51单片机中&#xff0c;定时器1工作在模式0&#xff0c;它和定时器0一样&#xff0c;TL1占低5位&#xff0c;TH1占高8位&#xff0c;合计13位&#xff0c;也是向上计数。 1、定时器1工作在模式0 1)、定时器1工作在模式0的框图…...

linux的服务管理

systemd systemd 是一个系统和服务管理器&#xff0c;用于Linux操作系统中&#xff0c;旨在替代传统的Unix系统V初始化系统&#xff08;SysV init&#xff09;。 不一定所有使用 yum 安装的软件都可以通过 systemctl start 来管理。能否通过 systemctl start 管理取决于软件包…...

动手学深度学习(Pytorch版)代码实践 -循环神经网络-53语言模型和数据集

53语言模型和数据集 1.自然语言统计 引入库和读取数据&#xff1a; import random import torch from d2l import torch as d2l import liliPytorch as lp import numpy as np import matplotlib.pyplot as plttokens lp.tokenize(lp.read_time_machine())一元语法&#xf…...

Python 学习之自动化运维技术(八)

Python 的自动化运维技术 Python的自动化运维技术是指利用Python编程语言和相关工具实现运维工作的自动化&#xff0c;以提高效率、减轻工作负担。以下是对Python自动化运维技术的清晰归纳和详细介绍&#xff1a; 一、自动化运维的核心优势 ● 提高效率&#xff1a;通过自动化脚…...

【python】PyQt5可视化开发,如何设计鼠标显示的形状?

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…...

利用大模型知识库,优化智能客服问答效果 | 创新场景

ITValue 痛点 SSC&#xff08; Share Service Center &#xff0c;共享服务中心&#xff09;是企业日常接触最多的场景之一&#xff0c;更多是对内服务&#xff0c;包括 HR 、财务、IT 等。该场景对专业度要求非常高&#xff0c;知识点非常多&#xff0c;对于知识的使用者或者查…...

物联网协议都包含哪些协议?

物联网协议是物联网生态系统中不可或缺的组成部分&#xff0c;它们负责处理和协调物联网设备之间的通信。具体介绍如下&#xff1a; Ethernet&#xff1a;以太网是一种有线网络协议&#xff0c;广泛应用于局域网络(LAN)中&#xff0c;提供稳定的高速数据传输。Wi-Fi&#xff1…...

面试专区|【52道微服务架构高频题整理(附答案背诵版)】

简述什么是微服务&#xff1f; 微服务是一种软件架构风格&#xff0c;它将应用程序拆分成一系列小型、独立的服务&#xff0c;每个服务都运行在其自己的进程中&#xff0c;通过轻量级通信机制进行通信。每个服务都具有明确的业务能力&#xff0c;并且可以独立开发、测试、部署…...

数据结构之算法的时间复杂度

1.时间复杂度的定义 在计算机科学中&#xff0c;算法的时间复杂度是一个函数&#xff0c;它定量描述了算法的运行时间。一个算法所花费的时间与其中语句的执行次数成正比列&#xff0c;算法中的基本操作的执行次数&#xff0c;为算法的时间复杂度 例1&#xff1a; 计算Func1…...

unity中物体被激活自动执行挂载代码

在Unity中,如果希望当物体被激活时自动执行特定的函数,可以利用 MonoBehaviour 的生命周期函数 OnEnable()。这个方法会在对象被激活时调用,可以用来执行初始化或者处理其他逻辑。以下是如何在脚本中使用 OnEnable() 方法: using UnityEngine;public class ActivateFuncti…...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现

目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻

在如今就业市场竞争日益激烈的背景下&#xff0c;越来越多的求职者将目光投向了日本及中日双语岗位。但是&#xff0c;一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧&#xff1f;面对生疏的日语交流环境&#xff0c;即便提前恶补了…...

ServerTrust 并非唯一

NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...

3-11单元格区域边界定位(End属性)学习笔记

返回一个Range 对象&#xff0c;只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意&#xff1a;它移动的位置必须是相连的有内容的单元格…...

Mysql8 忘记密码重置,以及问题解决

1.使用免密登录 找到配置MySQL文件&#xff0c;我的文件路径是/etc/mysql/my.cnf&#xff0c;有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...

[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】&#xff0c;分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...

R 语言科研绘图第 55 期 --- 网络图-聚类

在发表科研论文的过程中&#xff0c;科研绘图是必不可少的&#xff0c;一张好看的图形会是文章很大的加分项。 为了便于使用&#xff0c;本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中&#xff0c;获取方式&#xff1a; R 语言科研绘图模板 --- sciRplothttps://mp.…...

stm32wle5 lpuart DMA数据不接收

配置波特率9600时&#xff0c;需要使用外部低速晶振...

Neko虚拟浏览器远程协作方案:Docker+内网穿透技术部署实践

前言&#xff1a;本文将向开发者介绍一款创新性协作工具——Neko虚拟浏览器。在数字化协作场景中&#xff0c;跨地域的团队常需面对实时共享屏幕、协同编辑文档等需求。通过本指南&#xff0c;你将掌握在Ubuntu系统中使用容器化技术部署该工具的具体方案&#xff0c;并结合内网…...

Vue3中的computer和watch

computed的写法 在页面中 <div>{{ calcNumber }}</div>script中 写法1 常用 import { computed, ref } from vue; let price ref(100);const priceAdd () > { //函数方法 price 1price.value ; }//计算属性 let calcNumber computed(() > {return ${p…...