《深入理解Java虚拟机》(三)--Java内存模型与线程(3)

Java与线程

并发并不一定要依赖多线程(比如PHP中很常见的多进程并发),但是Java里面谈论到并发,大多与线程脱不开关系。

1/1 线程的实现

主流操作系统都提供了线程实现,Java语言则提供了在不同硬件和操作系统平台下对线程操作的统一处理,每个已经执行start()且还未结束的java.lang.Thread类的实例就代表了一个线程,Thread类与大部分API有明显的差异,它的所有关键方法都是声明Native的,一个Native方法意味着这个方法是使用非Java语言来实现的。线程实现的主要方式有三种:使用内核线程实现,使用用户线程实现和使用用户线程加轻量级进程混合实现。

  • 1.使用内核线程实现:内核线程就是直接由操作系统内核(Kernel)支持的线程,这种线程由内核来完成线程切换,内核通过调度器(Thread Scheduler)对线程进行调度,程序一般不会直接取使用内核线程,而是取使用内核线程的一种高级接口-----轻量级进程(LWP),轻量级进程就是我们通常意义上所说的线程,这种轻量级进程与内核之间1:1的关系成为1对1线程模型,如下图所示

    轻量级进程与内核线程之间1:1的关系

    优点:由于内核程序的支持,每个轻量级进程都成为了一个独立的调度单元,即使有一个轻量级进程发生了阻塞,也不会影响整个进程继续工作。
    缺点:由于是基于内核线程实现的,所以各种线程操作(如创建,析构和同步)都需要进行系统调用,调用的代价相对较高,需要在用户状态和内核状态来回切换,而且每个轻量级线程都需要内核进程的支持,因此一个系统支持轻量进程的个数是有限的。

  • 2.使用用户线程实现
    用户线程是指完全建立在用户空间的线程库上,系统内核不能感知线程存在。用户线程的建立、同步、销毁和调度完全在用户态中完成,不需要内核的帮助。这种进程与用户线程之间1:N的关系称为1对多线程模型,如下图所示。

    进程与用户线程之间1:N的关系

    优点:这种线程不需要切换到内核态,因此操作可以是非常快速而且低消耗的,也可以支持更大的线程数量,部分高性能数据库的多线程就是由用户线程实现。
    缺点:由于没有系统内核的支援,所有线程操作都是由用户程序自己处理,处理起来过于复杂,Java已经放弃使用它。

  • 3.使用用户线程加轻量级进程混合实现
    除了上述两种实现外,还有一种将内核线程与用户线程一起使用的实现方式。这种混合方式下,既存在用户线程也存在轻量级进程,用户线程与轻量级线程的数量比是不确定的,即为N:M的关系,如下图所示,这种就是多对多线程模式(让我想起了Mysql数据库的关系模式....)。

    用户线程与轻量级线程之间N:M的关系

    优点:用户线程完全建立在用户空间中,因此用户线程的创建、析构、切换等操作依然廉价,并且可以支持大规模的用户并发,书中并没有详细写出它的缺点0.0。

java线程的实现

在JDK1.2之后,线程模式为基于操作系统原生的线程模型来实现,线程模型只对并发规模和操作成本产生影响,对Java程序的编码和运行来说没有影响。Windows和Linux提供的线程模型为1对1,Solaris(Unix系列的操作系统)同时支持1对1和多对多,因此Solaris版的JDK中也对应提供了两个平台专有的虚拟机参数:-XX:+UseLWPSynchronization(默认值)和-XX:UseBoundThreads来明确指定虚拟机使用哪种线程模式。

1/2 Java线程调度

线程调度是指系统为线程分配处理器使用权的过程。主要调度方法有两种,分别是协同式线程调度,和抢占式线程调度。

  • 协同式线程调度:线程的执行时间由线程本身来控制,执行完成后,主动通知系统切换到另外一个线程上。
    优点:实现简单,切换操作对线程自己来说是可知的,所以不会产生线程同步的问题。
    缺点:线程执行时间不可控制,可能由于程序编写问题一直不告知系统进行线程切换,那么程序就会一直阻塞在那里,相当不稳定。
  • 抢占式线程调度:每个线程将由系统来分配时间,线程的切换不由线程本身来控制。
    优点:不会因为一个线程而导致整个系统的阻塞,Java使用的线程调度方式就是抢占式调度(JDK后续版本可能会提供协成方式来进行多任务处理)。
    缺点:需要处理线程安全的问题。

1/3 状态转换

Java语言定义了5种线程状态,在任意一个时间点,一个线程只能有且只有一种状态。这5种状态如下:

  • 新建(New):创建后尚未启动的线程处于这种状态。
  • 运行(Runnble):包括了操作系统线程状态中的Running和Ready,也就是处于此状态的线程有可能正在执行,也可能在等待CPU为他分配执行时间。
  • 无限期等待(Waiting):处于这种状态的线程不会被分配CPU执行时间,他们要等待被其他线程唤醒,以下方法可以让线程进入无限期等待。
    • 没有设置Timeout参数的Object.wait()方法。
    • 没有设置Timeout参数的Thread.join()方法。
    • LockSuppot.park()方法。
  • 限期等待(Timed Waiting):处于这种状态的线程也不会被CPU分配执行时间,不过无需等待被其他线程唤醒,在一定时间后他们会由系统自动唤醒,以下方法会让线程进入限期等待状态。
    • Thread.sleep()方法。
    • 设置了Timeout参数的Object.wait()方法。
    • 设置了Timeout参数的Thread.join()方法。
    • LockSuppot.parkNanos()方法。
    • LockSuppot.parkUntil()方法。
  • 阻塞(Blocked):线程被阻塞了,阻塞状态等待着获取到一个排他锁,这个时间将在另外一个线程放弃这个锁的时候发生;在程序等待进入同步区域的时候,线程将进入这种状态。
  • 结束(Terminated):已终止线程的线程状态,线程已经结束执行。

上述5种状态在遇到特定事件的时候可以相互转换,它们的转换关系如下图所示。


线程状态转换关系
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,254评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,875评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,682评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,896评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,015评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,152评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,208评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,962评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,388评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,700评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,867评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,551评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,186评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,901评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,142评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,689评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,757评论 2 351

推荐阅读更多精彩内容