2. Java线程模型
创始人
2024-02-03 09:37:24

1. 操作系统线程

无论使用何种编程语言编写多线程程序,最终都是通过调用操作系统的线程来执行任务。线程是CPU调度的最小执行单元。
线程有多种实现方式,常见的有:内核线程、用户线程、混合线程。
不同线程模型的主要区别在于线程的调度方不同,是操作系统还是虚拟机。

1.1 内核线程

由操作系统来负责多线程调度的多线程实现方式,叫做内核线程。
我们知道,**进程的地址空间分为内核空间和用户空间。**程序在内核空间执行时,CPU处于内核态,程序在用户空间执行时,CPU处于用户态。因此内核线程也叫做内核空间线程,或者内核态线程。
对于应用程序来说,其运行在用户空间,无法直接操作(创建、使用、销毁等)内核线程。因此,**操作系统暴露可以操作内核线程的系统调用,给应用程序使用。**因为系统调用比较底层,所以,大部分编程语言都对其进行封装,提供易用的线程接口,比如Linux中的pthread、C++中的std::thread等等。对于Java这种跨平台的语言来说,为了提供统一的线程操作接口,也会将操作系统提供的系统调用,封装为自己的线程类库。
内核线程模型,也叫做1:1模型。前面的1表示用户空间的一个线程,也就是在应用程序开发者眼中的一个线程,比如通过Java Thread创建的一个线程对象。后面的1表示内核空间的一个线程,也就是真正的线程。1:1模型指的就是:用户空间中的一个用户线程对应内核空间中的一个内核线程。

综上,应用程序运行在用户空间,通过系统调用才能实现对内核线程的操作。而系统调用会导致用户态和内核态的上下文切换,比较耗时。这是内核线程的一个弊端。

1.2 用户线程

为了解决内核线程存在的弊端(内核态和用户态的上下文切换),计算机科学家发明了用户线程。
类比内核线程,用户线程指的是线程的调度由虚拟机完成,而虚拟机本质上就是一个运行在用户空间的应用程序。
实现调度算法来调度线程的程序,叫做调度程序。用户线程的调度程序的实现思路,和内核线程的调度程序的实现思路基本一致。
实际上,用户线程只是一个外壳。从本质上来看,虚拟机执行三个线程,相当于轮询执行三段代码。所以应用程序操作用户线程(创建、使用、销毁等),都是在用户空间完成的,完全不需要操作系统内核的参与,这样就避免了系统调用带来的用户态和内核态的上下文切换。
不过,用户线程需要有专门的结构来记录上下文信息。除此之外,虚拟机也需要为每个用户线程维护独立的函数调用栈。
用户线程也叫做M:1线程模型。其中M表示M个用户线程,1表示1个内核线程。当虚拟机在运行时,操作系统会为其创建进程,而且是单线程的进程,这里的单线程指的是内核线程,即一个内核线程对应多个用户线程。

操作系统线程调度算法调度的是内核线程,为内核线程之间公平地分配时间片。不管虚拟机中创建多少个用户线程,它们都只能共享一个内核线程的CPU时间片。因此用户线程无法利用多核优势
除此之外,用户线程在使用上还有另外的限制。在用户线程中,我们无法使用阻塞模式的系统调用,比如read()、write()等阻塞IO系统调用。在内核线程中,当我们调用read()、write()等阻塞IO系统调用时,操作系统会让当前线程让出时间片,切换为其他线程执行。对于用户线程来说,当一个用户线程中的代码调用了阻塞IO系统调用时,对应的内核线程,就会被操作系统调度让出时间片,直到IO读写完成才会放入就绪队列。也就是说,只要一个用户线程阻塞了,其他用户线程也无法工作了。
解决这个问题的办法是,在用户线程中不要使用阻塞模式的系统调用,我们可以使用非阻塞的系统调用,内核线程在执行这类非阻塞的系统调用时,不需要让出时间片,可以继续执行后续的代码。
当然,相对于阻塞模式的系统调用,非阻塞模式的系统调用使用起来很不方便。比如调用非阻塞的write()系统调用,应用程序需要轮询查看是否写入完成。为了解决这个问题,一般支持用户线程的编程语言,会使用非阻塞函数模拟实现阻塞函数。在用法上,让程序员感知好像是在使用阻塞函数,实际上,底层使用的是非阻塞的系统调用来实现的。

1.3 混合线程

用户线程的优缺点
优点:避免了使用内核线程导致的内核态和用户态之间的上下文切换。
缺点:(1)一个进程内的用户线程无法利用多核并行运行;(2)一个用户线程调用阻塞系统调用会阻塞一个进程中的所有用户线程。
为了解决用户线程的缺点,计算机科学家发明了混合线程,又叫做M:N线程模型
**M:N线程模型表示一个进程中的M个用户线程对应N个内核线程,M一般大于N。**如果M等于N,那就退化成了1:1线程模型。如果M小于N,那么多余的内核线程就浪费掉。如果应用程序创建M个用户线程,那么虚拟机就会使用操作系统提供的系统调用,创建N个内核线程来服务这M个用户线程。M个用户线程并不会绑定在一个内核线程上,因此,一个用户线程阻塞并不会导致所有的用户线程阻塞。同时,M个用户线程分散在N个内核线程上,不同的用户线程可以分散在不同的CPU上执行,也就利用到了计算机多核的优势。

2. Java线程与操作系统线程的关系

Java线程有两种实现方式,一种叫Green Thread,一种叫Native Thread。
实际上,Green Thread就是用户线程模型,也就是M:1线程模型。Green Thread实际上只存在于早期jdk版本中,在JDK1.3中便已经废弃,被Native Thread取而代之。
Native Thread实际上就是内核线程模型,也就是1:1线程模型。Java提供的线程库,只不过是对操作系统提供的操作内核线程的系统调用的二次封装。线程的调度由操作系统来完成,因此,Java线程库实现起来非常简单。
每个操作系统的内核线程实现都有细微差别,比如线程的状态定义、线程的优先级划分等等都有可能不同。Java作为跨平台编程语言,需要提供统一编程接口。为了封装各个操作系统中线程实现的差别,Java线程库定义了自己的线程状态和优先级,以及和各个操作系统中线程状态和优先级的映射关系。

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...