并发编程-线程,JMM,JVM,volatile
1.线程
相信大家对线程这个名词已经很不陌生了,从刚开始学习java就接触到线程,先说说进程吧,进程就是系统分配资源的基本单位,线程是调度cpu的基本单位,进程由线程组成,一个进程至少又一个线程组成,线程寄生于进程。一个完整的线程由一个程序计数器,一组寄存器,和堆栈组成。其中程序计数器记录了线程下一个要执行的指令,寄存器保存这线程的一些变量,堆栈保存着线程当前的执行状态。
下面来说说线程的分类。看从不同的角度来分吧。从进程的角度来看,线程分为普通线程和守护线程。普通线程不用多说,基本的程序计数器,一组寄存器,和堆栈,普通线程拥有着正常的生命周期,但是守护线程他的生命周期很长,他是在一个进程中的所有普通线程都进入销毁生命周期的时候,守护线程才会进入生命的结束。下面举例来讲一讲守护线程的应用场景,JVM又一个内存回收机制也就是GC,他是贯穿JVM中所有普通线程的执行到销毁的生命周期,JVM的普通线程都执行完毕的时候,这个时候垃圾回收线程(守护线程)就销毁了,这个时候JVM也就可以退出了,但是如果垃圾回收线程不是守护线程,那么JVM会永远运行着。前面是从进程的角度来说的,如果从cpu调度的角度来说,线程可以分为用户线程(User Level Thread-ULT)和内核线程(Kernel Level Thread-KLT)。我们常说线程从用户态转化成内核态,下面内容会详细讲。
下面来详细的讲讲用户级线程和内核级的线程,也就是ULT和KLT。操作系统将内存空间分成了用户空间和内核空间,一般以4G的内存大小来说的话,内核空间大概占到一个G左右。顾名思义,内核空间运行着内核级线程,用户空间运行着用户级线程。在操作系统中,只有内核级线程拥有调度cpu的权限,像JVM或者其他软件运行的线程是没有直接使用cpu的权限的。下图1-1是用户空间和内核空间线程使用cpu过程的示意图:
图1-1
首先操作系统将使用cpu分为几个权限角色,以Linux为例,之前有ring0到ring3四个权限等级,现在只有ring3和ring0这两个权限角色,其中ring0拥有使用cpu的权限,ring3没有。从图中可以知道,ULT对应的权限是ring3,KLT对应的是ring0,也就是只有KLT才能有使用cpu的权限,所以当用户空间的线程想要使用cpu必须通过转换接口完成线程从用户态转为内核态,才能由系统根据他的调度算法去调度内核线程,并获取到cpu的时间片。值得注意得失java在1.2版本之前创建的线程都是基于用户态的线程,在1.2之后java创建的线程底层都是内核级的线程。
2.线程的生命周期
线程的生命周期相信很多java的程序员一口就能答得上来:创建,等待,就绪,运行,阻塞,销毁。其中线程的创建主要有四种方式:继承Java的Thread,实现Runnable接口,还有实现ExecutorService等等,后面的博文会详细介绍。下图2-1是我画的线程的一个生命周期图。
图2-1
2.并发
下面来简单讲讲并发,主要分三个问题来说,第一个什么是并发,第二个是为什么用到并发,第三个是并发存在的问题。
什么是并发,就是在一个操作系统中,同一时间段中有多个线程在cpu中处于运行的状态,在这里我要说的是,对于单核cpu和多核cpu或者多cpu的系统来说是不一样的。单核cpu严格意义上来讲,他在一个时间点上,cpu只可能运行一个线程,对于多核和多cpu的系统来说,在统一时间点上,他是有可能运行多个线程的。但是从宏观上来讲,由于cpu的速度很快,不管是单核还是多核亦或是多cpu的系统,它的都是并发的,就像我们的系统同时听着个和看着电影,你是感受不到的,从宏观感受上来说,这几个程序都是并发执行的。
为什么要用到并发,有几方面的原因,对于多核cpu或者多cpu的系统来说,并发能有效的提高cpu的利用率,不至于让cpu出现大量空闲的状态。再就是方便我们对业务进行拆分,提升整个应用的性能等等。
并发也存在一些问题,用到并发就必然要引出线程上下文切换的概念,线程上下文简单来说就是线程当前的运行状态。它包括线程的指令,程序指针,中间数据等。高并发的场景下,必然会导致线程上下文的高频切换,系统回去花费一部分资源和时间,这会导致cpu的效率变低。还有临界区线程安全的问题,容易出现死锁的问题。
下面我来先来说说线程的上下文切换,如下图2-1:
图2-1
如上图所示,当线程A获取到cpu时间片的时候,线程A开始执行,当线程A失去cpu时间片的时候,此时如果线程A还没有执行完,线程A的上下文信息包括指令,程序指针,以及一些中间数据都要保存下来,我们知道,每个线程在内存中都有自己的栈空间,这是JVM来规划的,此时线程A为了给线程B腾出cpu,她必须将线程的中间状态,也就是线程的上下文保存进入内存该线程的栈空间的Tss任务状态段。这样当线程B用完cpu,A拿到cpu时间片的时候,他才能准确的恢复线程上次执行的状态。
接下来说说临界区线程安全-死锁的问题,就通过一个小的Demo来演示一下,如下程序所示:
并发编程-线程,JMM,JVM,volatile的更多相关文章
- Java并发编程:JMM和volatile关键字
转载请标明出处: http://blog.csdn.net/forezp/article/details/77580491 本文出自方志朋的博客 Java内存模型 随着计算机的CPU的飞速发展,CPU ...
- java并发编程 线程基础
java并发编程 线程基础 1. java中的多线程 java是天生多线程的,可以通过启动一个main方法,查看main方法启动的同时有多少线程同时启动 public class OnlyMain { ...
- Java 并发编程 | 线程池详解
原文: https://chenmingyu.top/concurrent-threadpool/ 线程池 线程池用来处理异步任务或者并发执行的任务 优点: 重复利用已创建的线程,减少创建和销毁线程造 ...
- Python并发编程-线程同步(线程安全)
Python并发编程-线程同步(线程安全) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 线程同步,线程间协调,通过某种技术,让一个线程访问某些数据时,其它线程不能访问这些数据,直 ...
- Java并发编程:JMM(Java内存模型)和volatile
1. 并发编程的3个概念 并发编程时,要想并发程序正确地执行,必须要保证原子性.可见性和有序性.只要有一个没有被保证,就有可能会导致程序运行不正确. 1.1. 原子性 原子性:即一个或多个操作要么全部 ...
- Java并发编程:JMM (Java内存模型) 以及与volatile关键字详解
目录 计算机系统的一致性 Java内存模型 内存模型的3个重要特征 原子性 可见性 有序性 指令重排序 volatile关键字 保证可见性和防止指令重排 不能保证原子性 计算机系统的一致性 在现代计算 ...
- 并发编程(一)—— volatile关键字和 atomic包
本文将讲解volatile关键字和 atomic包,为什么放到一起讲呢,主要是因为这两个可以解决并发编程中的原子性.可见性.有序性,让我们一起来看看吧. Java内存模型 JMM(java内存模型) ...
- 【Java并发编程】6、volatile关键字解析&内存模型&并发编程中三概念
volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在Java 5之后,volatile关键字才得以 ...
- 【Java并发编程】11、volatile的使用及其原理
一.volatile的作用 在<Java并发编程:核心理论>一文中,我们已经提到过可见性.有序性及原子性问题,通常情况下我们可以通过Synchronized关键字来解决这些个问题,不过如果 ...
- java并发编程系列七:volatile和sinchronized底层实现原理
一.线程安全 1. 怎样让多线程下的类安全起来 无状态.加锁.让类不可变.栈封闭.安全的发布对象 2. 死锁 2.1 死锁概念及解决死锁的原则 一定发生在多个线程争夺多个资源里的情况下,发生的原因是 ...
随机推荐
- React 受控组件和非受控组件
需求用户名自动获取 onChange用户状态发生改变 就获取值 就是时时获取值 使用onChange 点击按钮 获取密码 只要绑定了点击事件 就可以获取值 通过 let usercont=event. ...
- python27期day17:re、logging日志模块、作业。
1.re: 正则就是用一些具有特殊含义的符号组合到一起(称为正则表达式)来描述字符或者字符串的方法.或者说:正则就是用来描述一类事物的规则.(在Python中)它内嵌在Python中,并通过 re 模 ...
- Azure产品整理
Azure的文档真是够落地,简明易懂. 计算 Linux 虚拟机:为 Ubuntu.Red Hat 等预配虚拟机 Windows 虚拟机 为 SQL Server.SharePoint 等预配虚拟机 ...
- luoguP3704 [SDOI2017]数字表格
题意 默认\(n\leqslant m\) 所求即为:\(\prod\limits_{i=1}^n\prod\limits_{j=1}^mf[\gcd(i,j)]\) 枚举\(\gcd(i,j)\)变 ...
- .Net反射-Type类型扩展
/// <summary> /// Type 拓展 /// </summary> public static class TypeExtensions { /// <su ...
- 区块链自问自答 day2
区块链自问自答 day2 区块链的自治性是如何达成的?为什么能够在去信任的环境下自由安全地交换数据? 区块链中有众多的节点,包含了恶意节点.故障节点.正常节点,想要这些节点共同做出一致的决定就需要 ...
- ABP 不包裹返回的数据
告诉abp不包裹返回的数据,返回的数据是什么 就是什么 不用再多包裹一次了. 用在 如:别人需要你提供接口 且给你指定了返回的数据结构. 源码:
- isinstance 与 issubclass
isinstance与issubclass都是用于判断的,有什么区别呢? 1. isinstance字面意思:实列, 用户判断对象所属类型,包含类的继承关系. 2. issubclass字面理解:是子 ...
- 【day05】css
一.盒模型(BoxModel) 1.width 宽度 2.height 高度 说明: 块元素和有宽高属性的标记(img,input) 能设置宽度和高度,而行元素不能设置宽高 3 ...
- 【递归】执行过程探究(c)
c语言 递归的执行过程探究 引用<c primer plus>第五版 9.3.1 递归的使用 /* recur.c -- recursion illustration */ #includ ...