并发编程-线程,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 死锁概念及解决死锁的原则 一定发生在多个线程争夺多个资源里的情况下,发生的原因是 ...
随机推荐
- jenkins如何构建C#代码写的网站
纯粹是因为同事习惯了写C#代码,开发的网站用C#编译, 对于习惯了用Maven编译的测试人员,真是一头雾水.不用jenkins吧,效率特别低,每次收到开发发过来的版本,还要进行数据库相关配置,是非常累 ...
- UGUI 逻辑以及实用性辅助功能
UGUI 有它的实用性, 可是也存在理解上的困难, 因为它在面板上的显示内容根据布局而变动, 如果不深入理解它的设计原理, 估计每次要进行程序上的修改都需要进行一次换算和测试过程. 1. 设置某UI的 ...
- Nginx配置参数中文详细说明
#定义Nginx运行的用户和用户组user www www;##nginx进程数,建议设置为等于CPU总核心数.worker_processes 8;##全局错误日志定义类型,[ debug | in ...
- NOIP 1999 导弹拦截
洛谷 P1020 导弹拦截 https://www.luogu.org/problemnew/show/P1020 JDOJ 1411: [NOIP1999]拦截导弹 T1 https://neooj ...
- 论文阅读笔记六十四: Architectures for deep neural network based acoustic models defined over windowed speech waveforms(INTERSPEECH 2015)
论文原址:https://pdfs.semanticscholar.org/eeb7/c037e6685923c76cafc0a14c5e4b00bcf475.pdf 摘要 本文研究了利用深度神经网络 ...
- Leetcode61.旋转链表
链表中的点已经相连,一次旋转操作意味着: 先将链表闭合成环 找到相应的位置断开这个环,确定新的链表头和链表尾 class Solution{ public: ListNode* rotateRight ...
- 使用element-ui的table组件时,渲染为html格式
背景 今天在做vue的项目时,使用到 element-ui 的 table 组件,使用富文本编辑器进行新增操作后,发现 html格式 并没有被识别 原因 在 element-ui 中,table组件默 ...
- 数据结构——顺序队列(sequence queue)
/* sequenceQueue.c */ /* 顺序队列 */ #include <stdio.h> #include <stdlib.h> #include <std ...
- GreenPlum 大数据平台--segment 失效问题恢复《二》(全部segment宕机情况下)
01,情况描述 主Segment和它的镜像都宕掉.导致了greenplum数据库不可用状态 02,重启greenplum数据库 gpstop -r 03,恢复 gprecoverseg 04,状态检查 ...
- 五年微软DevOps MVP (也称TFS MVP)
笔者有幸第五次被微软授予MVP称号,高兴之余,在这里简单的介绍一下MVP的基本情况: 谁是 MVP? Microsoft 最有价值专家 (MVP) 是热情地与社区分享知识的技术专家.他们总是处于&qu ...