Java线程概念

上一篇文章我们讲述了进程与线程概述,接下来的文章我们来探讨Java线程相关的内容。

接下来我们先了解几个概念性的问题

1、什么是Java线程

首先我们明白一个事实就是java是运行在JVM中的,而JVM是操作系统中的一个应用进程。那么如果你看了我的上一遍文章就应该很能够明白我们现在说的Java线程是指JVM会进程中的子任务了。从屏蔽所有方面(比如操作系统等)的细节,可以认为Java线程对应的调度是由JVM来操控的,因此私下可以这么认为,JVM定义了某种线程调度机制,并且在其中定义了有很多的执行队列,比如新建队列(new queue),就绪队列(ready queue),等待队列(waitting queue)等等

2、什么是Java线程组

JVM定义了在多线程运行系统中的线程组(ThreadGroup)对象,用于实现按照特定功能对线程进行集中式分组管理。

用户创建的每个线程均属于某线程组,这个线程组可以在线程创建时指定,也可以不指定线程组以使该线程处于默认的线程组之中。但是,一旦线程加入某线程组,该线程就一直存在于该线程组中直至线程死亡,不能在中途改变线程所属的线程组。 

例如:当Java的Application应用程序运行时,JVM创建名称为main的线程组。除非单独指定,在该应用程序中创建的线程均属于main线程组。在main线程组中可以创建其它名称的线程组并将其它线程加入到该线程组中,依此类推,构成线程和线程组之间的树型管理和继承关系。

3、Java线程有哪些状态(线程的状态控制)

新建(new):当利用new关键字创建线程对象实例后,它仅仅作为一个对象实例存在,JVM没有为其分配CPU时间片等线程运行资源; 

就绪(ready):在处于创建状态的线程中调用start方法将线程的状态转换为就绪状态。这时,线程已经得到除CPU时间之外的其它系统资源,只等JVM的线程调度器按照线程的优先级对该线程进行调度,从而使该线程拥有能够获得CPU时间片的机会。 

运行(running):线程获得了CPU 时间片(timeslice) ,执行程序代码

挂起(suspend):因为某种原因放弃了CPU 使用权,也即让出了CPU时间片,暂时停止运行。这时,线程将释放占用的所有资源,由JVM调度转入临时存储空间,直至应用程序恢复线程运行。

例如:运行(running)的线程执行Object.wait()方法,JVM会把该线程放入等待队列(waitting queue)中。运行(running)的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池(lock pool)中。

睡眠(sleep):在线程运行过程中可以调用sleep方法并在方法参数中指定线程的睡眠时间将线程状态转换为睡眠状态。这时,该线程在不释放占用资源的情况下停止运行指定的睡眠时间。时间到达后,线程重新由JVM线程调度器进行调度和管理。 

例如:运行(running)的线程执行Thread.sleep(long ms)或Thread.join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入可运行(runnable)状态。

终止(end):当线程体运行结束后,由JVM收回线程占用的资源时的状态。 

4、Java线程分类

非守护线程:常规的用户线程,用于执行各种各样的任务,可以执行各种各样业务逻辑。

守护线程:这个线程具有最低的优先级,在Java中比较是特殊的线程,用于为系统中的其它对象和线程提供服务。将一个用户线程设置为守护线程的方式是在线程对象创建之前调用线程对象的setDaemon方法。

比如垃圾回收线程就是一个很称职的守护者,它始终在低级别的状态中运行,用于实时监控和管理系统中的可回收资源。并且这种线程并不属于程序中不可或缺的部分。因此,当所有的非守护线程结束时,程序也就终止了,同时会杀死进程中的所有守护线程。反过来说,只要任何非守护线程还在运行,程序就不会终止。

守护线程和非守护线程的区别:唯一的不同之处就在于虚拟机的离开,如果用户线程已经全部退出运行了,只剩下守护线程存在了,虚拟机也就退出了。 因为没有了被守护者,守护线程也就没有工作可做了,也就没有继续运行程序的必要了。

5、Java线程之间是如何调度

线程调用的意义在于JVM应对运行的多个线程进行系统级的协调,以避免多个线程争用有限资源而导致应用系统死机或者崩溃。 

为了线程对于操作系统和用户的重要性区分开,JVM定义了线程的优先级策略。JVM将线程的优先级分为10个等级,分别用1-10之间的数字表示。数字越大表明线程的级别越高。相应地,在Thread类中定义了表示线程最低、最高和普通优先级的成员变量MIN_PRIORITY、MAX_PRIORITY和NORMAL_PRIORITY,代表的优先级等级分别为1、10和5。当一个线程对象被创建时,其默认的线程优先级是5。 

为了控制线程的运行策略,JVM定义了线程调度器来监控系统中处于就绪状态的所有线程。线程调度器按照线程的优先级决定哪个线程投入处理器运行。在多个线程处于就绪状态的条件下,具有高优先级的线程会在低优先级线程之前得到执行。线程调度器同样采用"抢占式"策略来调度线程执行,即当前线程执行过程中有较高优先级的线程进入就绪状态,则高优先级的线程立即被调度执行。具有相同优先级的所有线程采用轮转的方式来共同分配CPU时间片。 

在应用程序中设置线程优先级的方法很简单,在创建线程对象之后可以调用线程对象的setPriority方法改变该线程的运行优先级,同样可以调用getPriority方法获取当前线程的优先级。 

6、Java程序启动后,JVM创建了哪些线程

下面是一张java程序启动运行时获取的全部线程的图

参考:Java运行的基本线程解析

main线程:主线程,JVM创建的第一个线程,属于非daemon线程;

Reference Handler线程:JVM在创建main线程后就创建Reference Handler线程,其优先级最高,为10,它主要用于处理引用对象本身(软引用、弱引用、虚引用)的垃圾回收问题;关于引用,可以参考Java:对象的强、软、弱、虚引用这篇blog;

Finalizer线程:这个线程也是在main线程之后创建的,其优先级为8,主要用于在垃圾收集前,调用对象的finalize()方法;

1) 只有当开始一轮垃圾收集时,才会开始调用finalize()方法;因此并不是所有对象的finalize()方法都会被执行;

2) 该线程也是daemon线程,因此如果虚拟机中没有其他非daemon线程,不管该线程有没有执行完finalize()方法,JVM也会退出;

3) JVM在垃圾收集时会将失去引用的对象包装成Finalizer对象(Reference的实现),并放入ReferenceQueue,由Finalizer线程来处理;最后将该Finalizer对象的引用置为null,由垃圾收集器来回收;

4) JVM为什么要单独用一个线程来执行finalize()方法呢?如果JVM的垃圾收集线程自己来做,很有可能由于在finalize()方法中误操作导致GC线程停止或不可控,这对GC线程来说是一种灾难;

Signal Dispatcher线程:该线程用于处理操作系统发送给的JVM信号;Attach Listener 线程的职责是接收外部jvm命令,当命令接收成功后,会交给signal dispather线程去进行分发到各个不同的模块处理命令,并且返回处理结果。signal dispather线程也是在第一次接收外部jvm命令时,进行初始化工作。

Attach Listener线程:负责接收到外部的命令,而对该命令进行执行的并且把结果返回给发送者。通常我们会用一些命令去要求jvm给我们一些反馈信息,如:java -version、jmap、jstack等等。如果该线程在jvm启动的时候没有初始化,那么,则会在用户第一次执行jvm命令时,得到启动。


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

推荐阅读更多精彩内容

  • 【JAVA 线程】 线程 进程:是一个正在执行中的程序。每一个进程执行都有一个执行顺序。该顺序是一个执行路径,或者...
    Rtia阅读 2,766评论 2 20
  • 下面是我自己收集整理的Java线程相关的面试题,可以用它来好好准备面试。 参考文档:-《Java核心技术 卷一》-...
    阿呆变Geek阅读 14,812评论 14 507
  • 前言:虽然自己平时都在用多线程,也能完成基本的工作需求,但总觉得,还是对线程没有一个系统的概念,所以,查阅了一些资...
    justCode_阅读 705评论 0 9
  • 今天晚上我妈妈,带我去离我们家很近的德克士,去吃汉堡我非常的开心,在那里赠送给我了一个小本,小本很漂亮。在那里还有...
    碎片幻影阅读 194评论 0 0
  • 本文主要解决一个问题: 如何使用Shadow Map显示场景中的阴影 引言 是时候给场景中添加阴影了。阴影是非常消...
    闪电的蓝熊猫阅读 9,524评论 0 9