学习笔记8——JUC入门基础知识

学习笔记系列开头惯例发布一些寻亲消息

链接:https://baobeihuijia.com/bbhj/contents/3/199561.html
在这里插入图片描述

  • 进程和线程:进程是资源分配的最小单位,线程是CPU调度的最小单位

    • 进程和线程的主要区别(总结)_进程和线程的区别-CSDN博客
    • 进程和线程的区别(超详细)-CSDN博客
    • 在操作系统中能同时运行多个进程(程序);而在同一个进程(程序)中有多个线程同时执行
    • 一个进程中可以有多个线程,多个线程共享进程的和**方法区 (JDK1.8 之后的元空间)*资源,但是每个线程有自己的*程序计数器虚拟机栈本地方法栈
  • 并行和并发(从cpu的角度划分)

    • 并发:任务调度器使得CPU在同一段时间执行不同的任务,微观串行,宏观并行
    • 并行:在同一时刻cpu做多件事情的能力
  • 异步同步(从方法的角度划分)

    • 方法的执行需要等待别的结果返回,就是同步
    • 不需要等待别的方法结果返回,就是异步
  • 三种方法创建线程

    # 方法一
    Thread t = new Thread(){
    	public void run(){
    		xxxxx;
    	}
    };
    t.setName("t1")
    t.start();
    
    # 方法二
    Runnable r = new Runnable(){
    	public void run(){
    		xxxxxx;
    	}
    }
    Thread t = new Thread(r,"t2")
    t.start();
    
    # 方法三:简化lambda
    Runnable t = ()->{xxxxx;};
    Thread t = new Thread(r,"t2")
    t.start();
    
    # FutureTask是带有返回值的Runnable
    
    # windows
    tasklist 查看所有进程
    jps 显示所有的java进程
    taskkill 杀死某个进程
    
    # linux
    ps -fe 查看所有的命令进程
    ps -fe | grep java   筛选带有Java的
    jps 列出java进程
    kill 4202  杀死进程
    top 查看进程信息
    top -H -p 4262 查看该进程的线程信息
    jstack 4262 查看某个时刻的线程信息
    
  • 字节码放到方法区(二进制格式)

  • jvm启动main线程,并分配main栈帧

在这里插入图片描述

  • 线程上下文切换:cpu不再执行当前线程,转而执行另一个线程代码
    • 线程的cpu时间片用完
    • 垃圾回收
    • 有更高优先级的线程
    • 线程自己调用sleep,yield,wait,join,park,synchronized,lock方法
  • context switch的时候,需要操作系统保存当前线程的状态,包括:
    • 程序计数器、虚拟机栈中每个栈帧的信息(局部变量、操作数栈、返回地址)

在这里插入图片描述

  • 知识点

    • start 和 run 的区别(start是由别的线程调用从而启动A线程的,调用后不会影响该线程的本身进度,run是由线程A分配到cpu后才执行的)

    • sleep和yield

      • sleep就是放弃了cpu的使用,进入TIMED_WAITING阻塞状态
      • yield:让线程从RUNNABLE变为RUNNABLE 就绪状态
      • 在哪个线程下写 thread.sleep就是休眠哪个线程
      • 状态: NEW — RUNNABLE(可以被cpu调用的) — TIMED_WAITING (休眠)
      • 区别:cpu仍然会考虑yield,但是不会考虑sleep
    • 线程优先级setPriority:只是一个提示,调度器可以忽略这个信号

    • join:等待线程运行结束,哪个线程调用就等待哪个线程

    • join(时间):等待 min(时间,线程执行时间)

    • interrupt

      • 打断阻塞状态:sleep wait join 这些打断后isInterrupted重新置为false(打断后不能立即查看,需要等打断进入到异常块才能看到重置为false)

        public static void main(String[] args) throws InterruptedException {
            Thread t1 = new Thread(() -> {
                log.debug("sleep...");
                try {
                    Thread.sleep(5000); // wait, join
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            },"t1");
        
            t1.start();
            Thread.sleep(1000);
            log.debug("interrupt");
            t1.interrupt();
            // 这里如果没有等,可能还没有等t1重置为false就打印出true
            Thread.sleep(1000);
            log.debug("打断标记:{}", t1.isInterrupted());
        }
        
      • 打断正常状态:isInterrupted置为true,但是线程不会结束,需要自己再去判断是否真的要停止,获得currentThread(). isInterrupted 判断是否为true

        @Slf4j(topic = "c.Test12")
        public class Test12 {
        
            public static void main(String[] args) throws InterruptedException {
                Thread t1 = new Thread(() -> {
                    while(true) {
                        boolean interrupted = Thread.currentThread().isInterrupted();
                        // 没有判断的话就一直不会停止
                        if(interrupted) {
                            log.debug("被打断了, 退出循环");
                            break;
                        }
                    }
                }, "t1");
                t1.start();
        
                Thread.sleep(1000);
                log.debug("interrupt");
                t1.interrupt();
            }
        }
        
    • 两阶段终止模式(A线程如何优雅的停止B线程)
      在这里插入图片描述

      ```
      @Slf4j(topic = "c.TwoPhaseTermination")
      class TwoPhaseTermination {
          // 监控线程
          private Thread monitorThread;
          // 停止标记
          private volatile boolean stop = false;
          // 判断是否执行过 start 方法
          private boolean starting = false;
      
          // 启动监控线程
          public void start() {
              synchronized (this) {
                  if (starting) { // false
                      return;
                  }
                  starting = true;
              }
              monitorThread = new Thread(() -> {
                  while (true) {
                      Thread current = Thread.currentThread();
                      // 是否被打断
                      if (stop) {
                          log.debug("料理后事");
                          break;
                      }
                      try {
                          Thread.sleep(1000);
                          log.debug("执行监控记录");
                      } catch (InterruptedException e) {
                      }
                  }
              }, "monitor");
              monitorThread.start();
          }
      
          // 停止监控线程
          public void stop() {
              stop = true;
              monitorThread.interrupt();
          }
      }
      ```
      
    • park:代码会停止在执行park()的这一行,遇到interrupt后才会继续(标记为true),且以后再遇到park也不会停止,除非再次重置为false

    • 不推荐用的:

      • stop:强制让线程停止,即线程的资源可能还未被释放
      • suspend:挂起线程
      • resume 恢复线程运行
    • 主线程和守护线程:只要其他非守护线程结束,那么即使守护线程没有运行结束,也会停止运行(垃圾回收线程)

      t1.setDaemon(true); //设置守护线程
      
    • 线程的状态(操作系统层面)

      • 初始状态:仅语言层面创建线程对象,与操作系统未关联
      • 可运行状态:cpu可以调度
      • 运行状态:获取了cpu时间片
      • 阻塞:
      • 终止状态
    • 线程六种状态(java层面)

      • 初始状态:new但是尚未start
      • RUNNABLE:start之后线程的运行状态,可运行状态,阻塞状态
      • BLOCKED:拿不到锁
      • WAITING:join
      • TIMED_WAITING:sleep
      • TERMINATED:终止
      package cn.itcast.n3;
      
      import lombok.extern.slf4j.Slf4j;
      
      import java.io.IOException;
      
      @Slf4j(topic = "c.TestState")
      public class TestState {
          public static void main(String[] args) throws IOException {
              Thread t1 = new Thread("t1") {
                  @Override
                  public void run() {
                      log.debug("running...");
                  }
              };
      
              Thread t2 = new Thread("t2") {
                  @Override
                  public void run() {
                      while(true) { // runnable
      
                      }
                  }
              };
              t2.start();
      
              Thread t3 = new Thread("t3") {
                  @Override
                  public void run() {
                      log.debug("running...");
                  }
              };
              t3.start();
      
              Thread t4 = new Thread("t4") {
                  @Override
                  public void run() {
                      synchronized (TestState.class) {
                          try {
                              Thread.sleep(1000000); // timed_waiting
                          } catch (InterruptedException e) {
                              e.printStackTrace();
                          }
                      }
                  }
              };
              t4.start();
      
              Thread t5 = new Thread("t5") {
                  @Override
                  public void run() {
                      try {
                          t2.join(); // waiting
                      } catch (InterruptedException e) {
                          e.printStackTrace();
                      }
                  }
              };
              t5.start();
      
              Thread t6 = new Thread("t6") {
                  @Override
                  public void run() {
                      synchronized (TestState.class) { // blocked
                          try {
                              Thread.sleep(1000000);
                          } catch (InterruptedException e) {
                              e.printStackTrace();
                          }
                      }
                  }
              };
              t6.start();
      
              try {
                  Thread.sleep(500);
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
              log.debug("t1 state {}", t1.getState());
              log.debug("t2 state {}", t2.getState());
              log.debug("t3 state {}", t3.getState());
              log.debug("t4 state {}", t4.getState());
              log.debug("t5 state {}", t5.getState());
              log.debug("t6 state {}", t6.getState());
              System.in.read();
          }
      }
      

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[HTML]Web前端开发技术6(HTML5、CSS3、JavaScript )DIV与SPAN,盒模型,Overflow——喵喵画网页

希望你开心,希望你健康,希望你幸福,希望你点赞! 最后的最后,关注喵,关注喵,关注喵,佬佬会看到更多有趣的博客哦!!! 喵喵喵,你对我真的…

LDO版图后仿性能下降

记录一下LDO,debug 问题1: LDO后仿输出电压下降,前仿输出1.8V,后仿却输出只有1.58V。 解决办法: 功率管的走线问题,布线太少,存在IR drop问题。功率管的面积比较大,需要横竖都多…

解决Linux中文乱码、字体横向问题

解决Linux中文乱码问题 1、locale --查看当先系统编码集 2、echo $LANG --查看当前使用的语言 3、vim ~/.bash_profile --修改配置文件 4、加入以下语句 export LC_ALL"zh_CN.UTF-8" export LANG"zh_CN.UTF-8" 5、source ~/.bash_profile --更新配置文…

docker 安装elasticsearch集群

准备工作 docker 安装好,docker compose 安装好编辑好docker-compose.yml文件(本文会提供)生成elastic-certificates.p12密钥,与docker-compose文件在同一个目录(本文会介绍生成方式)准备elasticsearch配置…

Unittest单元测试之unittest用例执行顺序

unittest用例执行顺序 当在一个测试类或多个测试模块下,用例数量较多时,unittest在执行用例 (test_xxx)时,并不是按从上到下的顺序执行,有特定的顺序。 unittest框架默认根据ACSII码的顺序加载测试用例&a…

钢铁ERP系统有哪些?钢铁ERP软件哪家好用

不同的钢铁材料有差异化的产成品,而这些成品又有多元化的营销策略和制造工艺,每道生产工艺存在差异化的管理方式与策略,而不同的销售策略对应多样化的价格机制等,繁多的业务数据采集和分析工作量较大。 近些年制造工艺的变革也促…

线性表——(3)线性表的链式存储及其运算的实现

一、前言: 由于顺序表的存储特点是用物理上的相邻关系实现逻辑上的相邻关系,它要求用连续的存储单元顺序存储线性表中各数据元素,因此,在对顺序表进行插入、删除时,需要通过移动数据元素来实现,这影响了运行…

Java 线程同步和通信

Android 11 废弃了AsyncTask 线程 Thread: 通过start 开启 源码: start0 native方法 通过虚拟机跟操作系统交互 进程和线程区别: 进程是操作系统的独立区域,各个区域互不干扰,一个进程可以有多条线程同时工作,进程大于线程,线程依赖进程,线程间可以共享资源 Runnable: 接口…

利用 FormData 实现文件上传、监控网路速度和上传进度

利用 FormData 实现文件上传 基础功能:上传文件 演示如下: 概括流程: 前端:把文件数据获取并 append 到 FormData 对象中后端:通过 ctx.request.files 对象拿到二进制数据,获得 node 暂存的文件路径 前端…

用 LangChain 搭建基于 Notion 文档的 RAG 应用

如何通过语言模型查询 Notion 文档?LangChain 和 Milvus 缺一不可。 在整个过程中,我们会将 LangChain 作为框架,Milvus 作为相似性搜索引擎,用二者搭建一个基本的检索增强生成(RAG)应用。在之前的文章中&a…

华为电视盒子 EC6108V9C 刷机成linux系统

场景: 提示:这里简述项目相关背景: 家里装宽带的时候会自带电视盒子,但是由于某些原因电视盒子没有用,于是就只能摆在那里吃土,闲来无事,搞一下 问题描述 提示:这里描述项目中遇到…

[FC][常见Mapper IRQ研究]

本次IRQ研究了如下: VRC2&4(Mapper21,23,25) VRC3(Mapper73) VRC6(Mapper24 & Mapper26) VRC7(Mapper85) MMC3(Mapper4) MMC4(Mapper10) MMC5(Mapper5) Mapper18 Mapper64 Namco163(Mapper19) Sunsoft FME-7(Mapper69) 共计11种Mapper的IRQ操作使用例子 代码内有详细注…

【CANoe】CANoe工具使用-实现CAN通道的收、发、录、回放报文

目录 资源及目标 1. 配置工程 1.1 新建配置工程 1.2 配置两路CANoe虚拟通道 1.3配置CAN通道参数 1.3.1 配置CAN1类型(标准CAN或者CANFD),以及波特率(CANFD需要配置数据场和仲裁场两个段的波特率) 1.3.2配置CAN1…

电梯安全远程监控系统解决方案

一、方案背景 随着万丈高楼的平地起,电梯也成为了我们出入高层建筑最常用的工具之一。面对电梯数量的不断增加,电梯安全事故也是相继频发,因此关于电梯的安全运行就越来越受到社会各界的关注。电梯的使用在给人们出入高层建筑带来便利的同时&…

Normalizing Kalman Filters for Multivariate Time Series Analysis

l l l means latent state,LGM means ‘linear Gaussian state space models’ 辅助信息 作者未提供代码

高端网站设计公司 -蓝蓝设计数据可视化大屏服务

UI设计公司-蓝蓝设计(北京兰亭妙微科技有限公司)是一支由清华美院毕业的专业团队组成的设计公司。我们的设计师们在大屏科研信息软件UI设计领域拥有多年的工作经验和丰富的行业知识。我们对设计充满热爱,设计不仅是我们的专业和职业&#xff…

五、ZooKeeper的shell操作

目录 1、客户端连接 2、shell基本操作 2.1 操作命令

2023-12-02 LeetCode每日一题(拼车)

2023-12-02每日一题 一、题目编号 1094. 拼车二、题目链接 点击跳转到题目位置 三、题目描述 车上最初有 capacity 个空座位。车 只能 向一个方向行驶(也就是说,不允许掉头或改变方向) 给定整数 capacity 和一个数组 trips , trip[i] …

【SpringBoot3+Vue3】七【后续2】【番外篇】- (使用docke部署)

目录 一、maven打包后端服务 1、clean 2、package 3、查看jar包 二、部署java后端服务 1、使用dockerfile构建一个java17的镜像 1.1 使用dokcerfile构建容器命令 1.2 方式一 将jar打包进容器镜像 1.3 方式二 jar不打包进容器镜像,通过映射主机目录映射方式…

【数字图像处理】边缘检测

边缘检测是一种图像处理技术,用于在图像中识别和提取物体边缘的信息,广泛应用于计算机视觉和图像分析领域。本文主要介绍数字图像边缘检测的基本原理,并记录在紫光同创 PGL22G FPGA 平台的布署与实现过程。 目录 1 边缘检测原理 2 FPGA 布署…