Java多线程并发02——线程的生命周期与常用方法,你都掌握了吗

在上一章,为大家介绍了线程的一些基础知识,线程的创建与终止。本期将为各位带来线程的生命周期与常用方法。关注我的公众号「Java面典」了解更多 Java 相关知识点。

线程生命周期

一个线程不是被创建了马上就开始执行,也不是一直处于执行状态。在线程的整个生命周期中会经历新建(New)、
就绪(Runnable)、运行(Running)、阻塞(Blocked)和销毁(Terminated)5 种状态。

线程全生命周期.PNG

新建

指使用 new 关键字创建一个新的线程对象后,该线程就处于新建状态。此时仅由 JVM 为其分配内存,并初始化其成员变量的值。

就绪

当线程对象调用了 start() 方法之后,该线程处于就绪状态。JVM 会为其创建方法调用栈和程序计数器,等待调度运行。

运行

如果处于就绪状态的线程获得了 CPU 时钟,开始执行 run() 方法的线程执行体,则该线程处于运行状态。

阻塞

阻塞状态是指线程因为某种原因放弃了 CPU 使用权,暂时停止运行。阻塞的情况分三种:

  1. 等待阻塞(o.wait->等待对列):运行( running )的线程执行 o.wait( )方法,JVM 会把该线程放入等待队列(waitting queue) 中;
  2. 同步阻塞(lock->锁池):运行( running )的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则 JVM 会把该线程放入锁池( lock pool )中。
  3. 其他阻塞(sleep/join): 运行( running )的线程执行 Thread.sleep(long ms)或 t.join()方法,或者发出了 I/O 请求时,JVM 会把该线程置为阻塞状态。当 sleep() 状态超时、join() 等待线程终止或者超时、或者 I/O 处理完毕时,线程重新转入可运行( runnable )状态。

销毁

如果线程正常执行完毕后或线程被提前强制性的终止或出现异常导致结束,那么线程就要被销毁,释放资源。

线程常用方法

从线程的生命周期中,我们已经了解到了线程的一些常用方法。线程的常用方法有 wait,notify,notifyAll,sleep,join,yield等。

wait

  • 作用:强迫一个线程等待,线程进入 WATING 状态,只有等待另外线程的通知或被中断才会返回;
  • 注意:调用 wait() 方法后,会释放对象的锁。因此,wait 方法一般用在同步方法或同步代码块中。

sleep

  • 作用:强迫一个线程睡眠N毫秒,线程进入 TIMED_WATING 状态, 只有等待另外线程的通知或被中断才会返回;
  • 注意:与 wait 方法不同的是 sleep 不会释放当前占有的锁。

yield

  • 作用:使当前线程让出 CPU 执行时间片,与其他线程一起重新竞争 CPU 时间片;
  • 注意:一般情况下,优先级高的线程有更大的可能性成功竞争得到 CPU 时间片,但这又不是绝对的,有的操作系统对线程优先级并不敏感。

interrupt

  • 作用:中断一个线程,其本意是给这个线程一个通知信号,会影响这个线程内部的一个中断标识位;
  • 注意
  1. interrupt 不会改变线程的状态,即不会强制线程进入阻塞、终止等状态;
  2. 若线程处于 TIMED-WATING 状态,这时调用 interrupt()方法,会抛出 InterruptedException,从而使线程提前结束 TIMED-WATING 状态;
  3. 许多声明抛出 InterruptedException 的方法(如 Thread.sleep(long mills 方法)),抛出异常前,都会清除中断标识位,所以抛出异常后,调用 isInterrupted()方法将会返回 false;
  4. 可以调用 thread.interrupt()方法,在线程的 run 方法内部可以根据 thread.isInterrupted()的值来优雅的终止线程。

join

  • 作用:使当前线程转为阻塞状态,直到另一个线程结束,当前线程再由阻塞状态变为就绪状态;
  • 使用场景:主线程中启动子线程,主线程等待子线程的返回状态。
System.out.println(Thread.currentThread().getName() + "线程运行开始!");
Thread6 thread1 = new Thread6();
thread1.setName("线程 B");
thread1.join();
System.out.println("这时 thread1 执行完毕之后才能执行主线程");

notify

  • 作用:Object 类中的 notify() 方法,唤醒在此对象监视器上等待的单个线程;

如果所有线程都在此对象上等待,则会选择唤醒其中一个线程,选择是任意的,并在唤醒该线程前,调用该线程的 wait() 方法,在对象的监视器上等待,直到当前的线程放弃此对象上的锁定,才能继续执行被唤醒的线程,被唤醒的线程将以常规方式与在该对象上主动同步的其他所有线程进行竞争。类似的方法还有 notifyAll() ,唤醒在此监视器上等待的所有线程。

其他线程方法

  • isAlive():判断一个线程是否存活;
  • activeCount():程序中活跃的线程数;
  • enumerate():枚举程序中的线程;
  • currentThread():得到当前线程;
  • isDaemon():判断一个线程是否为守护线程;
  • setDaemon():设置一个线程为守护线程;
  • setName():为线程设置一个名称;
  • getPriority():获取当前线程的优先级;
  • setPriority():设置当前线程的优先级。
    注意:线程优先级高,被CPU调度的概率大,但不代表一定会运行,还有小概率运行优先级低的线程。

什么是守护线程

定义

守护线程——也称“服务线程”,他是后台线程,它有一个特性,即为用户线程提供公共服务,在没有用户线程可服务时会自动离开;

优先级

守护线程的优先级比较低,用于为系统中的其它对象和线程提供服务;

设置

通过 setDaemon(true)来设置线程为“守护线程”;将一个用户线程设置为守护线程的方式是在线程对象创建之前用线程对象的 setDaemon 方法;

特点

在 Daemon 线程中产生的新线程也是 Daemon 的;

example

垃圾回收线程就是一个经典的守护线程,当我们的程序中不再有任何运行的Thread,程序就不会再产生垃圾,垃圾回收器也就无事可做,所以当垃圾回收线程是 JVM 上仅剩的线程时,垃圾回收线程会自动离开。它始终在低级别的状态中运行,用于实时监控和管理系统中的可回收资源;

生命周期

守护进程(Daemon)是运行在后台的一种特殊进程。它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。也就是说守护线程不依赖于终端,但是依赖于系统,与系统“同生共死”。当 JVM 中所有的线程都是守护线程的时候,JVM 就可以退出了;如果还有一个或以上的非守护线程则 JVM 不会退出。

sleep() 与 wait() 的区别

  1. 所属类不同:sleep() 方法属于 Thread 类,wait() 方法属于 Object 类;
  2. 锁状态不同:sleep() 方法不会释放锁,而 wait() 方法会释放锁;
  3. 再次运行方式不同
  • sleep() 方法导致了程序暂停执行指定的时间,让出 cpu 该其他线程,但是他的监控状态依然保持者,当指定的时间到了又会自动恢复运行状态;
  • wait() 只有针对此对象调用 notify() 方法后,本线程才进入对象锁定池准备获取对象锁进入运行状态。

start() 与 run() 的区别

  1. 作用不用:start() 方法用来启动线程,run() 是线程逻辑的具体方法体;
  2. 状态不同:调用 start() 方法线程处于就绪状态,并没有运行,run() 执行时,线程处于运行状态。

多线程与并发系列推荐

Java多线程并发01——线程的创建与终止,你会几种方式

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