谈到Java多线程就涉及到多线程的模型及Java线程与底层操作系统之间的关系。正如我们熟知,现代机器可以分为硬件和软件两大块,如图2-5-1-1,硬件是基础,软件提供实现不同功能的手段。而且软件可以分为操作系统和应用程序,操作系统专注于对硬件的交互管理并提供一个运行环境给应用程序使用,应用程序则是能实现若干功能的并且运行在操作系统环境中的软件。同样,线程按照操作系统和应用程序两层次可以分为内核线程(Kernel Thread)和用户线程(User Thread)。

 

图2-5-1-1

所谓内核线程就是直接由操作系统内核支持和管理的线程,线程的建立、启动、同步、销毁、切换等操作都由内核完成。基本所有的现代操作系统都支持内核线程。用户线程指完全建立在用户空间的线程库上,由内核支持而无需内核管理,内核也无法感知用户线程的存在,线程的建立、启动、同步、销毁、切换完全在用户态完成,无需切换到内核。可以把用户线程看成是更高层面的线程,而内核线程则是最底层的支持,那么他们之间必然存在一定的映射关系,一般有三种常用的关系,下面将逐个列出。

① 一对一模型

一对一模型可以说是最简单的映射模型,如图2-5-1-2,KT为内核线程,UT为用户线程,每个用户线程都对应一个内核线程,由于每个用户线程都有各自的内核线程,所以他们互不影响,即使其中一个线程阻塞,也允许另一个线程继续执行,这无疑是此模型的优点,但也存在一个严重的缺陷,由于一对一的关系,有多少个用户线程就代表有多少个内核线程,而内核线程的开销较大,一般操作系统都会有内核线程数量的限制,用户线程的数量也被限制。

 

图2-5-1-2

② 多对一模型

第二种是多对一模型,如图2-5-1-3,可以清晰看到多个用户线程映射到同一个内核线程上,可以看成由一条内核线程实现若干个用户线程的并发功能,线程的管理在用户空间中进行,一般不需要切换到内核态,效率较高,而且比起一对一模型,支持的线程数量更大。但此模型有个致命的弱点是如果一个线程执行了阻塞调用,所有线程都将阻塞,并且任意时刻只能有一个线程访问内核。另外,对线程的所有操作都将由用户应用自己处理。所以一般除了在不支持多线程的操作系统被迫使用此模型外,在多线程操作系统中基本不使用。

 

图2-5-1-3

③ 多对多模型

多对多模型的提出是为了解决前面两种模型的缺点,如图2-5-1-4,多个用户线程与多个内核线程映射形成多路复用。前面提到的一对一模型存在受内核线程数量限制的问题,多对一模型虽然解决了数量限制问题,但它存在一个线程阻塞导致所有线程阻塞的风险,而且由于一个内核线程只能调度一个线程导致并发性不强。看看多对多模型如何解决这些问题,由于多对一是多对多的子集,所以多对多具备多对一的优点,线程数不受限制。除此之外,多个内核线程可处理多个用户线程,当某个线程阻塞时,将可以调度另外一个线程执行,这从另一方面看也是增强了并发性。

 

图2-5-1-4

三种模型各自有各自的特点,不同的现代操作系统可能使用不同的线程模型,例如linux和windows可能使用了一对一模型,而solaris和unix某些版本可能使用多对多模型。对于线程的创建和管理主要由线程库提供用户级别和内核级别两种API进行操作。用户级别由于不涉及内核操作,所有代码和数据结构均存放在用户空间,与此相反,内核级别由内核支持,将直接调用内核系统操作,代码和数据结构存在与内核空间中。在实际程序中我们一般不直接使用内核线程,用户线程与内核线程直接需要一种中间数据结构,它由内核支持且是内核线程的高级抽象,这个高级接口被称为轻量级进程(Light
Weight Process),下面简称LWP。图2-5-1-5是三种模型增加了轻量级进程的示意图,从某种层面上看,LWP最多算是广义的用户线程,并非狭义定义的用户进程,LWP线程库是以内核为基础,很多操作要进行内核调用,效率不高,如果要快速低消耗的操作则需要一个纯粹的用户线程,线程库完全建立在用户空间。于是可以看到一个进程P里面一般包含若干个用户进程,用户进程以某种关系对应轻量级进程,而轻量级进程则是内核线程的高级体现。如此一来,一个内核线程堵塞将导致LWP也阻塞,与LWP相连的用户线程也将阻塞。



图2-5-1-5

最后要谈谈Java线程与底层操作系统的关系,由于Java通过JVM封装了底层操作系统的差异,所以Java线程也必然是要封装不同操作系统提供一个统一的并发定义,在JDK发展历史上,java语言开发者曾经通过一类叫“绿色线程(Green Threads)”的用户线程进行实现Java线程,但从jdk1.2开始,java线程使用操作系统原生线程模型实现,也就是说Java线程的实现通过不同操作系统提供的线程库分别实现,JVM根据不同操作系统的线程模型对Java线程进行映射,假如Java运行在windows系统上,它通常直接使用Win32
API实现多线程,假如Java运行在linux系统则直接使用Pthread线程库实现多线程。这样一来就顺利隐藏了底层实现细节,提供给开发者就是一个具有统一抽象的线程语义。

喜欢研究java的同学可以交个朋友,下面是本人的微信号:

Java多线程模型的更多相关文章

  1. Java多线程之~~~使用Exchanger在线程之间交换数据[这个结合多线程并行会有解决很多问题]生产者消费者模型

    http://blog.csdn.net/a352193394/article/details/39503857  Java多线程之~~~使用Exchanger在线程之间交换数据[这个结合多线程并行会 ...

  2. Java多线程与并发模型之锁

    这是一篇总结Java多线程开发的长文.文章是从Java创建之初就存在的synchronized关键字引入,对Java多线程和并发模型进行了探讨.希望通过此篇内容的解读能帮助Java开发者更好的理清Ja ...

  3. 多线程并发之java内存模型JMM

    多线程概念的引入是人类又一次有效压寨计算机的体现,而且这也是非常有必要的,因为一般运算过程中涉及到数据的读取,例如从磁盘.其他系统.数据库等,CPU的运算速度与数据读取速度有一个严重的不平衡,期间如果 ...

  4. 【java多线程系列】java内存模型与指令重排序

    在多线程编程中,需要处理两个最核心的问题,线程之间如何通信及线程之间如何同步,线程之间通信指的是线程之间通过何种机制交换信息,同步指的是如何控制不同线程之间操作发生的相对顺序.很多读者可能会说这还不简 ...

  5. java多线程的基础-java内存模型(JMM)

    在并发编程中,需要处理两个关键问题:线程之间如何通信,以及线程之间如何同步.通信是指线程之间如何交换信息,在命令式编程中,线程之间的通信机制有两种:内存共享和消息传递.      同步是指程序中用于控 ...

  6. Java内存模型JMM 高并发原子性可见性有序性简介 多线程中篇(十)

    JVM运行时内存结构回顾 在JVM相关的介绍中,有说到JAVA运行时的内存结构,简单回顾下 整体结构如下图所示,大致分为五大块 而对于方法区中的数据,是属于所有线程共享的数据结构 而对于虚拟机栈中数据 ...

  7. JAVA多线程-内存模型、三大特性、线程池

    一.线程的三大特性 原子性.可见性.有序性 1)原子性,即一个操作或者多个操作要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行.原子性其实就是保证数据一致.线程安全一部分. 2)可见性,即 ...

  8. Java 多线程(六)之Java内存模型

    目录 1. 并发编程的两个问题 2 CPU 缓存模型 2.1 CPU 和 主存 2.2 CPU Cache 2.3 CPU如何通过 Cache 与 主内存交互 2.4 CPU 缓存一致性问题 3 Ja ...

  9. Java多线程中的内存模型

    转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6536131.html  一:现代计算机的高速缓存 在计算机组成原理中讲到,现代计算机为了匹配 计算机存储设备的 ...

随机推荐

  1. python的字符串

    首先,字符串是python内置的数据类型,其特点是用引号引起来,并且可以是使用单引号('字符串'),双引号("字符串"),三个引号('''字符串''' 和""& ...

  2. 用js来实现那些数据结构09(集合01-集合的实现)

    说到集合,第一个想到的就是中学学到的那个数学概念:集合.在我们开始集合相关的js实现前,我们有必要来了解一下什么是集合以及集合的数学概念. 好吧,我们一起来复习一下早就被我们遗忘的集合. 集合是由一组 ...

  3. [HNOI 2004]树的计数

    Description 一个有n个结点的树,设它的结点分别为v1, v2, …, vn,已知第i个结点vi的度数为di,问满足这样的条件的不同的树有多少棵.给定n,d1, d2, …, dn,编程需要 ...

  4. [usaco6.1.1Postal Vans]

    来自FallDream的博客,未经允许,请勿转载,谢谢. 给你一个4*n的棋盘,问从(1,1)出发恰好经过所有格子一次的走法数量.(n<=1000) 插头dp,用f[i][j][k]表示转移到第 ...

  5. Xamarin开发缺少的android_m2repository_rxx.zip下载地址以及MD5

    android_m2repository_rxx.zip下载地址以及MD5, 注意:下载后需要改文件名,改为 MD5的值.zip  例如:android_m2repository_r29.zip 需改 ...

  6. 关于Matchvs一些使用心得与建议

    我的项目是类似<贪吃蛇>玩法的一款IO游戏,就是几个玩家在游戏界面中可以吃食物,也可以相互吃,吃了食物或对方都会变大这样子.我是在用cocos creator做完前端开发的部分后,开始接入 ...

  7. C语言 递归 汉诺塔问题 最大公约数问题

    函数不能嵌套定义,但能嵌套调用(在调用一个函数的过程中再调用另一个函数) 函数间接或直接调用自己,称为递归调用  汉诺塔问题 思想:简化为较为简单的问题 n=2 较为复杂的问题,采用数学归纳方法分析 ...

  8. 深入理解final关键字

    在了解了final关键字的基本用法之后,这一节我们来看一下final关键字容易混淆的地方. 1.类的final变量和普通变量有什么区别? 当用final作用于类的成员变量时,成员变量(注意是类的成员变 ...

  9. Linux平台安装MongoDB

    MongoDB 提供了 linux 各发行版本 64 位的安装包,你可以在官网下载安装包. 下载地址:https://www.mongodb.com/download-center#community ...

  10. TP中的AJAX返回ajaxReturn()

    系统支持任何的AJAX类库,Action类提供了ajaxReturn方法用于AJAX调用后返回数据给客户端.并且支持JSON.XML和EVAL三种方式给客户端接受数据,通过配置DEFAULT_AJAX ...