深入理解线程的原理和用法

2023-11-15

Java中的线程:
程序、进程和线程
1程序是一段静态的代码,它是应用程序执行的蓝本
2进程是程序的一次动态执行过程。它对应了从代码加载、执行到执行完毕的一个完整过程。作为蓝本的程序可以被多次加载到系统的不同内存区域分别执行,形成不同的进程。
3线程是进程内部单一的一个顺序控制流。一个进程在执行过程中,可以产生多个线程。每个线程也有自己产生、存在和消亡的过程。
使用线程的目的就是 增加并发性。
就绪态:1分配指令计数器pc 2在jvm中拥有独立的虚拟机栈、本地方法栈和PC寄存器(可以随时占用处理机)会跟主线程争夺处理机 主方法执行完毕 就主线程就执行完 jvm中就绪池中还有两个线程
处于阻塞态的资源 :释放jvm的空间 不会征用处理机
开始状态线程 :在jvm中开辟空间
(1) Java线程的调度策略 依赖系统的调度策略 没有规律可言!
① 随机调度(随机从就绪态中拿一个)
② 一旦线程在执行,只有当前线程执行完或者执行到某个可停止点,才会调度其他线程。
③ C语言,windows系统底层:先来先服务,时间片轮转
后台线程:前台线程执行完毕 后台线程将自动结束
线程是不安全的: 会出现“100-40=80”的情况 所以需要尽可能避免这种情况currentThread当前线程对象的地址
(1) currentThread.getName:当前线程对象的线程名
(2) mathine1.setName(“m1”);设置线程名
(3) SetPriority:设置优先级
① 优先级:有三种

  1. 十级:MAX_PRIORITY
  2. 五级:默认NORM_ PRIORITY=5
  3. 一级:MIN_PRIORITY
    ② 由主线程创建的线程默认和主线程相同
  1. Yield():(当某一个线程执行,不会主动放弃处理机)主动放弃处理机,从运行态直接进入就绪态
    (1) 当某个线程占用占用处理机,主动放弃处理机,给同优先级或更高优先级的线程占用处理机的机会,从运行态直接进入就绪态。
  2. setDaemon():设定为后台线程(必须在该线程启动(start())之前)
    (1) 所有前台进程结束后,后台线程自动终止
    在这里插入图片描述
public class Mathine extends Thread{
  public void run(){
  	   
    for ( int a=0;a<10;a++){
                                                
   	System.out.println(currentThread().getName()+":"+a);//拿到线程的地址  然后再拿到线程的名字
       try {			//阻塞态条件满足后 会处于就绪态 
            sleep(100);//休眠期  处于阻塞态:1主动放弃处理机sleep  2 等待io的操作 等待用户输入数据 3执行某段代码的时候发现代码上锁了 4处于对象阻塞池 
           }catch (InterruptedException e) {throw new RuntimeException(e);
           }
         }
        }
   
      public static void main(String[] args) {//通过main方法进行主线程,在栈中开辟主方法栈帧空间开辟主线程的run方法栈帧。主方法执行完毕,主线程也会结束。
        Mathine mathine1 = new Mathine();//在栈区 给mathine1线程 开辟 run方法栈帧
        Mathine mathine2 = new Mathine();//在栈区 给mathine1线程 开辟 run方法栈帧
            //mathine1.setName("m1");
           // mathine2.setName("m2");
   	    mathine1.setPriority(Thread.MAX_PRIORITY);//设置线程的优先级  高优先
           mathine2.setPriority(Thread.MIN_PRIORITY);//设置线程的优先级   低优先
   	   // System.out.println("Priority of m1:"+mathine1.getPriority());
        // System.out.println("Priority of m2:"+mathine2.getPriority());
   	    mathine1.start();  //执行mathine1线程 栈的run()方法空间  此时处于就绪状态(1在栈中分配了空间 ,2分配指令计数器pc,可以随时占用处理机)
           mathine2.start();//mathine2线程栈的 run方法空间 此时处于就绪状态
           mathine1.run(); //开辟主线程的run方法栈帧。主线程主动执行了 mathine1的run 方法 Thread.currentThread().getName()//得到线程地址跟线程名

线程的3中常用创建方式
第一种:继承Thread这个类 , 然后复写该类的run方法, 通过new 该类 调用start方法来开启线程。
第二种:
**加粗样式

第三种:通过自定义线程池来调用
线程池可以自定义创建 也可以直接调用API创建
在这里插入图片描述

我们通常通过ThreadPoolExecutor来创建线程池,具体细节就不细说了
在这里插入图片描述

通过调用execute()方法来开启线程
在这里插入图片描述

这三种创建线程的方式推荐通过线程池,因为通过线程池固定了线程的数量,不会因为线程大量的新生死亡操作而消耗CPU。

在这里插入图片描述

这两个方法的区别:如果直接调用线程的run()方法,会在当前线程执行,调用线程的start方法则会在新的线程执行。

在这里插入图片描述

为什么会出现线程不安全的问题
对于多个线程操作堆中的同一个对象,因为线程是独立的,对象是共享的,而且JVM采用了分片方式,即每个线程只会执行jvm给你分配的时间片,如果时间耗尽或者到了安全停止点,那么该线程就会让出资源,给其他线程。这就导致,线程执行语句不会全部执行完,解决方法,让所有执行语句看成一个整体,只有整体执行完毕才会让出资源。即使用 synchronized

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

深入理解线程的原理和用法 的相关文章

随机推荐

  • 设计模式:外观模式

    有些人可能炒过股票 但其实大部分人都不太懂 这种没有足够了解证券知识的情况下做股票是很容易亏钱的 刚开始炒股肯定都会想 如果有个懂行的帮帮手就好 其实基金就是个好帮手 支付宝里就有许多的基金 它将投资者分散的资金集中起来 交由专业的经理人进
  • Redis——认识Redis

    简单介绍 Redis诞生于2009年 全称是Remote Dictionary Server 远程词典服务器 是一个基于内存的键值型NoSQL数据库 特征 键值 Key value 型 value支持多种不同数据结构 功能丰富 单线程 每个
  • Qt简单的异步操作实现方法

    Qt简单的异步操作实现方法 在实际应用中 经常会遇到一些耗时操作 导致了主线程的阻塞 这时候可以使用异步操作来避免阻塞 Qt的异步操作需要使用下面的库 include
  • python写邮箱验证工具_Python编写的Linux邮件发送工具

    之前有用过Linux自带的mail工具来定时发送邮件 但是要装mailx还有配mail rc 这还比较正常 关键是到了ubantu下这工具用起来真是操蛋 如果哪天其他的unix like操作系统也有需求 那就太麻烦了 所以我用自带的pyth
  • QT界面布局和设计

    一 设计 对功能和模块进行分析 然后设计对应的模块 将每个模块都用widget展示作为组件 工程结构示例 二 完成模块 代码分别设计各个组件 合适即可 三 主界面连接 主界面连接各个子模块 在这里插入代码片 include AutoFlaw
  • CAN总线详解及STM32的CAN通信编程指南

    对于CAN通信而言 本人之前也未接触了解过 由于实习的技术要求 因此也花费了一段时间对CAN通信进行学习 并且实现了基于STM32的CAN环回静默模式通信 因此写一遍比较详细的文章对该内容进行总结 本文的参考资料有STM32的中文参考手册
  • 【JAVA】Could not resolve all dependencies for configuration ‘:detachedConfiguration1‘

    build gradle 中添加 id net linguica maven settings version 0 5 plugins id org springframework boot version 2 3 3 RELEASE id
  • 【华为OD统一考试B卷

    华为OD统一考试A卷 B卷 新题库说明 2023年5月份 华为官方已经将的 2022 0223Q 1 2 3 4 统一修改为OD统一考试 A卷 和OD统一考试 B卷 你收到的链接上面会标注A卷还是B卷 请注意 根据反馈 目前大部分收到的都是
  • centos7 安装jdk17

    默认情况下 yum 仓库中是没有jdk 17 的 只有jdk 11 所以我们不能直接用yum 安装 需要手动下载进行配置工作 下载文件 wget https download oracle com java 17 latest jdk 17
  • 网页与服务器数据库数据交互,网页与ACCESS数据库如何实现数据交互?

    1 打开access 单机菜单栏创建 选择表 单击列 选择下拉菜单中的字段类型 单机列名更改字段名称 2 添加完成后单击保存成test accdb 新建c 窗体程序 3 using System using System Collectio
  • 今日算法中数据结构知识练习 (7-19)【4】

    Date 2019 07 19 1 两个指针 P 和 Q 分别指向单链表的两个元素 P 所指元素是 Q 所指元素前驱的条件是 P gt next Q 2 串是一种特殊的线性表 其特殊性体现在 数组元素是一个字符 3 下列文件中属于逻辑结构文
  • uniapp onHide()和onUnload()的使用

    小程序onHide 和onUnload onHide 触发的场景 导航页1 gt gt 导航页2 会触发导航页1 onHide 导航页 gt gt 子页面 会触发导航页 onHide 子页面1 gt gt 子页面2 会触发子页面1 onHi
  • linux查询mysql内存使用率_MySQL内存使用率无限增长

    背景 收到内存报警的信息以后 从监控中发现MySQL服务器的内存使用率在不断的增长 附图 虽然进行了重启 但是内存占用率依然会不停的增长 大约在半个月左右的时间内又把内存消耗完毕 场景 未搭建场景 数据库版本 5 7 12 分析 PS 时间
  • 精简CUDA教程——CUDA Runtime API

    精简CUDA教程 CUDA Runtime API tensorRT从零起步迈向高性能工业级部署 就业导向 课程笔记 讲师讲的不错 可以去看原视频支持下 Runtime API 概述 环境 图中可以看到 Runtime API 是基于 Dr
  • (C语言)在屏幕上输出对应的图案(* ** *** *****.....)

    在屏幕上输出如下的图案 根据上面图片可以看出来 前7行中下一行的星比前一行多出两个星 第8行到第13行是下一行比前一行少2个星 代码为 include
  • el-select远程搜索:remote-method遇到的坑

    在使用远程搜索的时候 就是每次发请求获取数据然后选择 会出现选择后总是会出现选择紊乱的情况 在使用debugger后排查了很久 发现每次选择内容后 都会触发 remote method这个事件 也就是继续会发请求 然后获取到新的数据重新赋值
  • 什么是值传递,什么是引用传递

    一般认为 java中基础类型数据传递都是值传递 java中实例对象的传递是引用传递 值传递是对基本型变量而言 传递的是该变量的一个副本 不影响该原变量 而引用传递是一般对于对象型变量而言 传递的是该对象地址的副本 并不是原对象本身 1 值传
  • linux bash环境配置文件

    linux bash环境配置文件 你是否会觉得奇怪 怎么我们什么动作都没有进行 但是一进入 bash 就取得一堆有用的变量了 这 是因为系统有一些环境配置文件案的存在 让 bash 在启动时直接读取这些配置文件 以规划好 bash 的操作环
  • ubuntu切换国内镜像源,加速apt-get下载速度

    ubuntu切换国内镜像源 加速apt get下载速度 如题 使用apt get命令安装包时 由于系统自带的下载源在国外服务器上 故下载速度较慢 若切换为国内源 将显著提升下载速度 下列是设置步骤 STEP 1 查找适合自己系统的镜像源配置
  • 深入理解线程的原理和用法

    Java中的线程 程序 进程和线程 1程序是一段静态的代码 它是应用程序执行的蓝本 2进程是程序的一次动态执行过程 它对应了从代码加载 执行到执行完毕的一个完整过程 作为蓝本的程序可以被多次加载到系统的不同内存区域分别执行 形成不同的进程