线程相关学习记录(1)

news2024/9/24 9:20:46

认识线程

什么是线程

进程: 正常电脑中启动的某个程序应用,并且会获得计算机分配的资源(cpu,内存,硬件设备)
线程: 进程中为了完成某个功能,内部划分出的不同的资源分配单位。通常在多线程OS中,线程是计算机分配处理器的单位。当程序应用创建出的线程需要使用硬件设备,进行I/O读写文件的时候,就需要从用户级程切换为内核级线程,内核级线程是操作系统直接进行管理和调度的。

线程模型

线程模型: 用户级线程和内核级线程之间的对应关系。

多对一:

在这里插入图片描述

  • 在多对一模型中,多个用户级线程映射到某一个内核线程上
  • 线程管理由用户空间中的线程库处理,这非常有效
  • 但是,如果进行了阻塞系统调用,那么即使其他用户线程能够继续,整个进程也会阻塞
  • 由于单个内核线程只能在单个 CPU 上运行,因此多对一模型不允许在多个 CPU 之间拆分单个进程

从并发性角度来总结下,虽然多对一模型允许开发人员创建任意多的用户线程,但是由于内核只能一次调度一个线程,所以并未增加并发性。现在已经几乎没有操作系统来使用这个模型了,因为它无法利用多个处理核。

一对一:

在这里插入图片描述

  • 一对一模型克服了多对一模型的问题,因为有多个内核级线程,所以可以在多个cpu之间切割任务
  • 一对一模型创建一个单独的内核线程来处理每个用户线程,操作系统来管理和调度
  • 但是,管理一对一模型的开销更大,涉及更多开销和减慢系统速度
  • 此模型的大多数实现都限制了可以创建的线程数

多对多:

在这里插入图片描述

  • 多对多模型将任意数量的用户线程复用到相同或更少数量的内核线程上,结合了一对一和多对一模型的最佳特性
  • 用户对创建的线程数没有限制
  • 阻止内核系统调用不会阻止整个进程
  • 进程可以分布在多个处理器上
  • 可以为各个进程分配可变数量的内核线程,具体取决于存在的 CPU 数量和其他因素

java线程和操作系统的线程的区别

java线程在不同的操作系统中有不同的实现方式,Linux下是基于pthread库实现的轻量级进程,Windows下是原生的系统Win32
API提供系统调用从而实现多线程,所以本质上java线程就是基于操作系统的线程

java线程状态

查看java.lang.Thread类的源码,可以发现java中的线程状态有六种:

在这里插入图片描述

  // 尚未启动的线程的线程状态。
        NEW,

        /**
         * 可运行线程的线程状态。可运行的线程状态在Java虚拟机中执行,但可能正在等待来自操作系统的其他资源,例如处理器。
         */
        RUNNABLE,

        /**
         * 该线程被阻止等待监视器锁定。处于阻塞状态的线程正在等待监视器锁定
         * 等待进入同步块/方法,或调用Object.wait()方法之后被重新唤醒等待进入同步块/方法
         * 调用wait方法之后的线程状态变化历程为:   WAITING--> RUNNABLE ---->  BLOCKED
         */
        BLOCKED,

        /**
         * 线程变为WAITING状态可能是因为调用了
         * Object.wait()方法   (没有超时参数)
         * Thread.join()      (没有超时参数)
         * LockSupport.park()
         */
        WAITING,

        /**
         *
         * 定时等待,在WAITING状态的基础指定了时长,可能是调用下面的方法
         * Thread.sleep(long millis)
         *  Object.wait(long timeout)
         *  Thread.join(long millis)
         *  LockSupport.parkNanos(Object blocker, long nanos)
         *  LockSupport.parkUntil(Object blocker, long deadline)
         */
        TIMED_WAITING,

        /**
         * 完成执行
         */
        TERMINATED;

Thread类常用方法

start/run方法:

run方法是实际线程运行代码逻辑的方法,是从实现Runnable接口中得来的,但是如果直接调用run方法并不会启动一个线程,而是一个普通的调用对象实例的方法;

start方法才是真正启动一个线程的方法,start方法是用native关键字修饰的方法,表明是一个本地方法。我理解的本地方法就是用其他语言写好的一个方法,加上native关键字之后就会区分出本地方法,在JVM内存模型中有一个特定的区域就是本地方法栈,是线程私有的区域。在这个native方法中,应该会去创建一个线程并去调用写好的run方法。

sleep / yield

调用sleep方法之后线程状态会变为TIMED_WAITING状态,线程会放弃CPU资源,但是不会放弃锁,
调用yield无参方法之后线程会进入WAITING状态,但是如果调用的是yield有参方法,则会进入TIMED_WAITING状态;
yield虽然也会放弃cpu资源,但是会倾向于让更高优先级的线程先执行。

interrupt方法

使用interrupt方法会将线程的是否中断标志设为true,但是我看这个方法的源码里并没有这个设置过程,在Thread也没有找到这个中断标志位,而是去调用了一个native方法去完成这个工作。
如果当前线程已经处于BLOCKED,WAITING,TIMED_WAITING状态,再去调用这个线程的interrupt方法,会抛出InterruptedException异常,可以在捕获这个异常的catch块中做结束动作,同样的如果线程已经调用了inerrupt方法,再去进入BLOCKED,WAITING,TIMED_WAITING状态也会抛出同样的异常。

setDaemon

在Thread类中有一个 boolean daemon 属性,是否设置为守护线程,默认为false,如果设置true,当程序中没有其他线程运行的时候守护线程会自动结束。java中GC回收就是守护线程。

线程如何运行

线程的运行,包括java代码的运行都和JVM息息相关。

java运行时区域(JVM)

在这里插入图片描述

Java堆(线程共享)

所有的对象实例都在这里分配内存

方法区(线程共享)

它用于存储已被虚拟机加载的类信息、常量、静态变量等数据。

本地方法栈(线程私有)

就是java代码中用native关键字修饰的方法

java虚拟栈(线程私有)

主要存储的是局部变量表,操作数栈,动态链接,返回地址等等。 虚拟栈就是一个一个帧栈组成的,而每一个帧栈对应的就是java中的每一个方法,没调用一个方法,就会创建一个帧栈。

程序计数器(线程私有)

如果执行的是普通java代码,存放的就是下一条需要执行的jvm字节码指令的地址;如果执行的是native方法,则为空。

线程安全

线程不安全的问题就是多个线程同时访问和操作同一个资源导致出现意料之外的问题。

java内存模型(JMM)

在这里插入图片描述

JMM规定了所有变量都存储在主内存中,每个线程会有自己的工作内存,其中工作内存中存储的变量都是主内存中的变量的副本,线程对变量的访问或者更新操作都必须在本工作内存中进行,然后再刷新到主内存中。

JMM的三大性质:原子性,可见性,有序性。

java实现原子性

java提供了锁和循环CAS的方式保证了原子性,这里的锁包括了synchronized关键字,也有 java.util.concurrent.locks.Lock 接口的锁;
循环CAS则是使用了CAS算法的代码类,比如原子类AtomicInteger,AtomicLong等等这些原子工具类。

CAS算法就是在线程想要更新变量的时候有三个操作:

  • 先到主存中获取到要更新的这个变量的最新值
  • 和之前获取主存中的这个变量进行比较
  • 如果之前获取的值和最新获取的值一样,那就更新;否则就自旋重试或者阻塞

简短点概括就是: 获取-----比较------更新

java实现可见性

实现的方式有volatile关键字,synchronized关键字,final关键字修饰变量也可以实现。

final关键字也能实现的原因是:

只要对象是正确构造的(被构造对象的引用在构造函数中没有“逸出”),那么不需要使用同步(lock、volatile)就可以保证任意线程都能看到这个 final 域在构造函数中被初始化之后的值。

java实现有序性

java提供了synchronized和volatile关键字来保证操作之间的有序性。

Happens-before 原则

happens-before原则定义如下:

(1): 如果第一个操作happens-before于第二个操作,那么第一个操作的结果对于第二个操作就是可见的,并且第一个操作的顺序排在第二个操作的前面
(2): 在不影响happens-before结果的前提下,允许对happens-before的操作进行 重排序

as-if-serial只能作用单线程,happens-before则是提供跨线程的内存可见性保证。

as-if-serial: cpu和编译器在对指令进行重排序的时候,不管如何重排,单线程环境下都不能改变执行结果。

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

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

相关文章

[附源码]Python计算机毕业设计SSM基于框架的旅游管理系统(程序+LW)

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

MyBatis详细学习笔记

一、MyBatis简介 MyBatis是ORM框架,即对象关系映射框架。 二、搭建MyBatis 不同的MySQL版本使用的JDBC不同 com.mysql.jdbc.Driver // MySQL 5 com.mysql.cj.jdbc.Driver // MySQL 8不同版本的MySQL的url也不同 jdbc:mysql://localhost:3306/ssm // MySQL 5 jd…

神仙级Python办公自动化教程(非常详细),从零基础入门到精通,轻松玩转Excel,从看这篇开始

Excel是Office办公中使用非常频繁的一个表格制作、数据分析与图表制作的组件。随着现在数据处理量越来越大,日常办公中很多重复性工作耗费了广大办公人员越来越多的时间,那么如何才能化繁为简,提高办公自动化水平呢?借助Python中的…

【小程序】小程序中插槽使用

💭💭 ✨:小程序插槽   💟:东非不开森的主页   💜: 没关系 天空越黑星星越亮💜💜   🌸: 如有错误或不足之处,希望可以指正,非常感谢&#x1f60…

大学生个人网站作业 超简单DIV CSS个人网页成品 简单个人网站作业模板 HTML个人网页设计下载 简约黑白色个人主页

🎉精彩专栏推荐👇🏻👇🏻👇🏻 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 💂 作者主页: 【主页——🚀获取更多优质源码】 🎓 web前端期末大作业…

Redis大key多key拆分方案

业务场景中经常会有各种大key多key的情况, 比如: 1:单个简单的key存储的value很大 2:hash, set,zset,list 中存储过多的元素(以万为单位) 3:一个集群存储了…

Java脚本化编程实践整理 ScriptEngineManager万字详解

文章目录认识Java支持脚本语言的意义Java对JavaScript的支持Rhino/Nashorn概述Nashorn的目的实践操作HelloWorld执行脚本文件代码脚本语言使用Java的变量执行脚本方法/函数脚本语言使用Java的类对象脚本语言实现Java的接口脚本的多个作用域脚本语言使用Java的数据类型创建java对…

[附源码]计算机毕业设计基于Web的软考题库平台Springboot程序

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

CSS固定定位与粘性定位4大企业级案例

前面两篇文章为大家详细讲解了相对定位与绝对定位的应用场景和案例。如果想了解的可以在公众号里面查看去看。本小节我们学习下固定定位与粘性定位的应用场景和案例。 属性值 描述 relative 相对定位 相对于自身正常位置进行位置的调整 absolute 绝对定位 相对于其最近的定…

如何用实时数据分析辅助企业智能决策,这个高效的解决方案了解下?

随着产业互联网的发展,企业数字化能力的边界也在不断拓展,除了对海量数据的获取、处理及应用需求以外,更快地获取实时数据也开始成为大数据时代各行各业的共同目标。 在企业的业务经营中,实时数据是营销、运维、决策的重要支撑&am…

ChatGPT OpenAI 让学习更加高效工作中实现效率翻倍

ChatGPT是一款由OpenAI开发的聊天机器人,它具有出色的自然语言处理能力,能够与人类进行真实的对话。它的核心技术是GPT-3语言模型,能够自动学习语言特征,并进行语义理解、文本生成等任务。ChatGPT具有快速回答和丰富内容的特点&am…

Mac M1使用brew安装nvm

nvm作为node版本管理器,全称node version manager,可以管理安装的node和node-sass版本。在macOS系统上的安装步骤如下: *本机使用的是M1芯片,终端配置文件默认使用.zshrc 1. 安装homebrew /usr/bin/ruby -e "$(curl -fsSL h…

2022_SPIC_FANet

Feature aggregation network for RGBD saliency detection 1. 动机 如何将RGB和Depth充分挖掘和融合仍是一个关键问题。 第一个问题是如何从深度图中充分挖掘几何信息,从而可以可靠地反映场景的空间结构。 第二个问题是如何有效地融合外观信息和几何信息&…

koa项目

一.koa起步 1.项目初始化 执行 npm init -y ,生成 package.json npm init -y2.安装koa 执行命令 npm install koa3.编写基本app 创建 src/main.js //1.导入koa包 const Koa new require("Koa");//2。实例化app对象 const app new Koa();//3.编写中间件 app.…

基于C#+Mysql实现(WinForm)企业的设备管理系统【100010018】

企业的设备管理系统 1 引言 企业的设备管理在企业的生产制造和管理过程之中意义比较重大,明确企业的设备的产权和维护成本对于企业的成本控制和财务管理之中起到了重要的作用。随着市场竞争的加剧,现代企业所处的市场环境发生了深刻的变革,…

JDK19都出来了~是时候梳理清楚JDK的各个版本的特性了【JDK13特性讲解】

JDK各个版本特性讲解-JDK13特性 一、JAVA13概述 2019年9月17日,国际知名的OpenJDK开源社区发布了Java编程语言环境的最新版本OpenJDK13。 Features:总共有5个新的JEP(JDK Enhancement Proposals): http://openjdk.java.net/projects/jdk/13/ Features: …

java基于springboot的人事管理系统-计算机毕业设计

开发环境 开发语言:Java 框架:springboot JDK版本:JDK1.8 服务器:tomcat7 数据库:mysql 数据库工具:Navicat11 开发软件:eclipse/myeclipse/idea Maven包:Maven 项目介绍 在这个计…

m基于GA遗传优化的三维工程施工设施布局算法matlab仿真,显示二维和三维布局优化效果

目录 1.算法描述 2.仿真效果预览 3.MATLAB核心程序 4.完整MATLAB 1.算法描述 GA把问题的解表示成“染色体”,在算法中也即是以二进制编码的串。并且,在执行遗传算法之前,给出一群“染色体”,也即是假设解。然后,把…

Matplotlib学习笔记(第二章 2.13 Matplotlib中的图形(三))

图例(Legends) legend()函数,使用MATLAB兼容的图例,放置函数自动生成图形图例。 感谢查尔斯特沃迪对图例功能的投入。 Fig. 19: Legend 文本对象的Tex表示法(TeX-notation for text objects) 下面是Matplotlib内部的mathtext工程支持的许多Tex表达式…

基于C#+SQLServer 2005实现(WinForm)校园卡消费信息系统【100010013】

校园卡消费信息管理系统 一、前言 1.1 选题说明 校园卡消费信息系统是一个实用并且与我们的学校生活密切相关的管理信息系统;如果能够很好的研究、开发并加以利用,校园卡的相关业务会变得更加简单、学生能更便利地进行消费同时准确了解自己的消费情况…