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

news2024/11/19 7:45:25

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

链接: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();
          }
      }
      

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

矩阵起源入选IDC《中国大数据管理解决方案技术评估,2023》

近日,矩阵起源作为典型代表厂商入选国际数据公司IDC发布的《中国大数据管理解决方案技术评估,2023》。 在该评估中,IDC认为,矩阵起源超融合异构数据库 MatrixOne 具备如下优势: 将存储、计算、事务三层结解耦,以极致灵…

uni-app 微信小程序之自定义圆形 tabbar

文章目录 1. 自定义tabbar效果2. pages新建tabbar页面3. tabbar 页面结构4. tabbar 页面完整代码 1. 自定义tabbar效果 2. pages新建tabbar页面 首先在 pages.json 文件中,新建一个 tabbar 页面 "pages": [ //pages数组中第一项表示应用启动页&#xff…

代理服务器的IP和端口是什么意思?

代理服务器的地址和端口:基础概念解析 如果我们将其与在互联网发明之前我们的老一辈之间用于交流的经典书信进行类比,那么地址就相当于信封上的寄件人地址,而端口就相当于收信人地址。然而,与传统信件不同,这里需要确切…

【蓝桥杯软件赛 零基础备赛20周】第6周——栈

文章目录 1. 基本数据结构概述1.1 数据结构和算法的关系1.2 线性数据结构概述1.3 二叉树简介 2. 栈2.1 手写栈2.2 CSTL栈2.3 Java 栈2.4 Python栈 3 习题 1. 基本数据结构概述 很多计算机教材提到:程序 数据结构 算法。 “以数据结构为弓,以算法为箭”…

使用YOLOv8训练自己的数据集

🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 | 接辅导、项目定制 拉取项目 git clone https://github.com/ultralytics/ultralytics安装依赖 cd ultralytics pip install -r requirement.txt pip instal…

某60区块链安全之薅羊毛攻击实战二学习记录

区块链安全 文章目录 区块链安全薅羊毛攻击实战二实验目的实验环境实验工具实验原理实验内容薅羊毛攻击实战二 实验步骤EXP利用 薅羊毛攻击实战二 实验目的 学会使用python3的web3模块 学会分析以太坊智能合约复杂场景下薅羊毛攻击漏洞及其利用 找到合约漏洞进行分析并形成利…

springboot+vue志愿者在线报名服务管理系统java毕业设计源码+数据库

vuespringboot志愿服务管理系统 本项目是springbootvueElementuimysql源码 开发工具,idea和eclipse都可以,MySQL 源码下载地址 https://download.csdn.net/download/yibo2022/88401958?spm1003.2166.3001.6637.3https://download.csdn.net/download/yibo2022/884…

深入理解Zookeeper系列-1.初识Zoookeeper

👏作者简介:大家好,我是爱吃芝士的土豆倪,24届校招生Java选手,很高兴认识大家📕系列专栏:Spring源码、JUC源码、Kafka原理、分布式技术原理🔥如果感觉博主的文章还不错的话&#xff…

LLM算法工程师面试题总结

一、请简述对大模型的基本原理和架构的理解。 大型语言模型如GPT(Generative Pre-trained Transformer)系列是基于自注意力机制的深度学习模型,主要用于处理和生成人类语言。下面简要概述了它们的一些基本原理和架构特点: 基本原…

springBoot3.2 + jdk21 + GraalVM上手体验

springBoot3.2 jdk21 GraalVM上手体验 SpringBoot2.x官方已经停止维护了,jdk8这次真的得换了🤣 可以参考官方文章进行体验:https://spring.io/blog/2023/09/09/all-together-now-spring-boot-3-2-graalvm-native-images-java-21-and-virt…

对el-button封装使用

x改变el-button样式并且多处使用 el-button封装&#xff1a; <template><el-buttonclass"my-btn":style"{ width }":disabled"disabled"click"myClick"mouseenter"person.active true"mouseleave"person.ac…

计算机视觉(OpenCV+TensorFlow)

计算机视觉&#xff08;OpenCVTensorFlow&#xff09; 文章目录 计算机视觉&#xff08;OpenCVTensorFlow&#xff09;前言3.图像金字塔3.1 高斯金字塔3.2 拉普拉斯金字塔 4.图像轮廓图像边缘和图像轮廓的区别检测图像绘制边缘 5.轮廓近似外接矩形外接圆 6. 模板匹配6.1 什么是…

Python实现FA萤火虫优化算法优化BP神经网络分类模型(BP神经网络分类算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 萤火虫算法&#xff08;Fire-fly algorithm&#xff0c;FA&#xff09;由剑桥大学Yang于2009年提出 , …

系列十五、SpringBoot的启动原理分析

一、概述 所谓SpringBoot的启动原理&#xff0c;翻译成大白话就是"当我们在主启动类上运行run方法时&#xff0c;SpringBoot底层到底做了什么事情&#xff0c;能够帮助我们启动一个Spring的web应用"&#xff0c;上边用大白话解释了一下什么是SpringBoot的启动原理&am…

百度文心一言AI大模型,解读徐礼昭提出的“三体零售”模型

徐礼昭提出的“三体零售”模型是一种创新的零售理论模型&#xff0c;该模型将零售基础物质、零售商业能量和零售数字化系统视为一个相互作用的复杂有机体。这一理论模型为零售行业的发展提供了全新的视角和更高维度的认知。 首先&#xff0c;零售基础物质是零售行业的基石&…

cocos 关于多个摄像机,动态添加节点的显示问题,需要动态修改layer。(跟随摄像机滚动)(神坑官网也不说明一下)

参考文章&#xff1a;Cocos 3.x 层级Layer - 简书 2D镜头跟随应该怎么实现呢 - Creator 3.x - Cocos中文社区 关于多个摄像机&#xff0c;动态添加节点的显示问题&#xff0c;需要动态修改layer&#xff1f; 场景&#xff1a;在制作摄像机跟随角色移动功能时&#xff0c;新增…

RPG项目01_场景及人物动画管理器

基于“RPG项目01_UI登录”&#xff0c;新建一个文件夹名为Model&#xff08;模型&#xff09; 将资源场景拖拽至Model中 找到相应场景双击进入 红色报错部分Clear清掉即可&#xff0c;我们可以重做 接下来另存场景 起名为Game 点击保存 场景就保存至Scene中了 在文件夹下新创建…

jsp前端输入中文数据传到controller变成问号?的解决办法

还是写老师布置的实验的时候&#xff0c;解决了xml文件找不到的问题之后又遇到新的问题&#xff1a;前端登录处输入用户名和密码&#xff0c;结果明明输入的用户名是对的密码也是对的&#xff08;输入的用户名是中文&#xff09;&#xff0c;它就是显示用户名或密码错误。然后我…

2012-2021年银行数字化转型程度数据(根据年报词频计算)

2012-2021年银行数字化转型程度&#xff08;根据年报词频计算&#xff09; 1、时间&#xff1a;2012-2021年 2、指标&#xff1a;银行名称、年份、数字化转型程度 3、范围&#xff1a;52家银行&#xff08;上海银行、中信银行、中国银行、交通银行、光大银行、兰州银行、兴业…

电子学会C/C++编程等级考试2021年06月(四级)真题解析

C/C++等级考试(1~8级)全部真题・点这里 第1题:数字三角形问题 (图1) 图1给出了一个数字三角形。从三角形的顶部到底部有很多条不同的路径。对于每条路径,把路径上面的数加起来可以得到一个和,你的任务就是找到最大的和。 注意:路径上的每一步只能从一个数走到下一层上和它…