并发编程-线程,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 死锁概念及解决死锁的原则 一定发生在多个线程争夺多个资源里的情况下,发生的原因是 ...
随机推荐
- UGUI 逻辑以及实用性辅助功能
UGUI 有它的实用性, 可是也存在理解上的困难, 因为它在面板上的显示内容根据布局而变动, 如果不深入理解它的设计原理, 估计每次要进行程序上的修改都需要进行一次换算和测试过程. 1. 设置某UI的 ...
- Linux下JDK中文字体乱码
java生成图片的时候用到字体,但是liunx系统没有这些字体需要把C:\Windows\Fonts 上传到/usr/local/jdk1.8.0_171/jre/lib/fonts 重启tomcat ...
- JDOJ 1065 打倒苏联修正主义
JDOJ 1065 https://neooj.com/oldoj/problem.php?id=1065 题目描述 [”客观”背景]苏修是苏联修正主义的简称.从1956年到1966年的10年间,过去 ...
- nginx 403问题
错误排查 https://blog.csdn.net/onlysunnyboy/article/details/75270533 关闭 SELinux https://blog.csdn.net/ed ...
- Python搭建HTTP服务
我们平时可能会需要HTTP服务,本机搭建一个服务器来完成有些过于繁琐,这时就可以用python帮我们搭建一个HTTP服务器,省时高效. python 2.x 输入命令:python -m Simple ...
- 调试经验分享-让自己的电脑充当WI-Fi模块,用来抓取连接Wi-Fi模块APP上的通信数据
需求 手头有了厂家的APP和Wi-Fi模块 在已经知道APP是通过TCP连接Wi-Fi模块(8266), 同时也知道了连接的端口号的 情况下如何知道厂家的APP发送给Wi-Fi模块的数据 打开自己的笔 ...
- Windows下找到JVM占用资源高的线程
与linux下top命令直接显示进程下线程资源占用不同,Windows下默认任务管理器只能显示出进程的资源占用,jconsle等工具也只能显示出java进程资源占用,无法显示出进程能具体线程的资源占用 ...
- [LeetCode] 290. Word Pattern 词语模式
Given a pattern and a string str, find if str follows the same pattern. Here follow means a full mat ...
- 【2019年07月22日】A股最便宜的股票
查看更多A股最便宜的股票:androidinvest.com/CNValueTop/ 便宜指数 = PE + PB + 股息 + ROE,四因子等权,数值越大代表越低估. 本策略只是根据最新的数据来选 ...
- python读写符号的含义
r 打开只读文件,该文件必须存在. r+ 打开可读写的文件,该文件必须存在. w 打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失.若文件不存在则建立该文件. w+ 打开可读写文件,若文件 ...