Java中的线程状态(详见Java线程状态及转换-MarchOn):

  • wait:Object类的实例方法,释放CPU执行权,进入等待状态,直到  被中断、被拥有该对象锁的线程唤醒(notify或notifyAll)、wait时间到了自己唤醒 三者之一发生。会释放所持有的对象锁。(关于 wait、notiy、notifyAll的配合原理见后面

示例:wait()和notify()因为会对对象的“锁标志”进行操作,所以它们必须在获得对象锁后执行即在 synchronized函数或synchronized block中进行调用,否则如果虽然能编译通过,但在运行时会发生IllegalMonitorStateException的异常。

 package buaa.act.ucar.imtg.main;

 /**
* @author zsm
* @date 2017年3月3日 上午10:23:53
*/
public class Test extends Thread {
public static void main(String[] args) {
// TODO Auto-generated method stub
Test test = new Test();
test.start();
try {
synchronized (test) {
Thread.sleep(1000);
System.out.println("wake the thread in main...");
test.isFire = true;
test.notify();
} } catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} /**
* 线程锁
*/
private final Object object = new Object(); private volatile boolean isFire = false; @Override
public void run() {
System.out.println("开始执行线程。。。");
System.out.println("进入等待状态。。。");
synchronized (this) {
try {
while (!isFire) {
wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("线程结束。。。");
}
}
  • sleep:Thread类的静态方法,释放CPU执行权,等待指定时间后自己醒来。不会释放所持有对象的锁。
  • join:Thread实例的方法,释放CPU执行权,等待被调用join方法的线程结束才继续执行本线程下面的操作。不会释放所持有对象的锁。
  • interrupt:1、打断处于等待状态的线程(对于阻塞状态的线程不起作用,如因synchronized方法或代码块等而阻塞的线程):在wait或sleep的线程、在等待线程结束的线程(join的调用者)可以被中断(叫打断更贴切,fuck翻译),如果被中断,会抛出InterruptedException;2、对非等待状态的线程调用interrupt不会抛异常,需要手动检测线程状态并做相应处理。

两个示例:

 //打断处于等待状态的线程
public class InterruputSleepThread {
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread() {
@Override
public void run() {
//while在try中,通过异常中断就可以退出run循环
try {
while (true) {
//当前线程处于阻塞状态,异常必须捕捉处理,无法往外抛出
TimeUnit.SECONDS.sleep(2);
}
} catch (InterruptedException e) {
System.out.println("Interruted When Sleep");
boolean interrupt = this.isInterrupted();
//中断状态被复位
System.out.println("interrupt:"+interrupt);
}
}
};
t1.start();
TimeUnit.SECONDS.sleep(2);
//中断处于阻塞状态的线程
t1.interrupt(); /**
* 输出结果:
Interruted When Sleep
interrupt:false
*/
}
} //对处于运行状态的线程标记中断
public class InterruputThread {
public static void main(String[] args) throws InterruptedException {
Thread t1=new Thread(){
@Override
public void run(){
while(true){
//判断当前线程是否被中断
if (this.isInterrupted()){
System.out.println("线程中断");
break;
}
} System.out.println("已跳出循环,线程中断!");
}
};
t1.start();
TimeUnit.SECONDS.sleep(2);
t1.interrupt(); /**
* 输出结果:
线程中断
已跳出循环,线程中断!
*/
}
} //阻塞状态的线程打断无效
public class SynchronizedBlocked implements Runnable{ public synchronized void f() {
System.out.println("Trying to call f()");
while(true) // Never releases lock
Thread.yield();
} /**
* 在构造器中创建新线程并启动获取对象锁
*/
public SynchronizedBlocked() {
//该线程已持有当前实例锁
new Thread() {
public void run() {
f(); // Lock acquired by this thread
}
}.start();
}
public void run() {
//中断判断
while (true) {
if (Thread.interrupted()) {
System.out.println("中断线程!!");
break;
} else {
f();
}
}
} public static void main(String[] args) throws InterruptedException {
SynchronizedBlocked sync = new SynchronizedBlocked();
Thread t = new Thread(sync);
//启动后调用f()方法,无法获取当前实例锁处于等待状态
t.start();
TimeUnit.SECONDS.sleep(1);
//中断线程,无法生效
t.interrupt();
}
}
  • yield:Thread的静态方法,此方法只是使当前线程重新回到可执行状态,不会阻塞线程,因此执行yield()的线程有可能在进入到可执行状态后马上又被执行。实际上,当某个线程调用了yield方法暂停之后,只有优先级与当前线程相同,或者优先级比当前线程更高的处于就绪状态的线程才会获得执行的机会。
  • suspend:已过时,弃用
  • resume:已过时,弃用
  • stop:已过时,弃用

wait、notify、notifyAll三者的异同:(可参阅 彻底理解wait、notify、notifyAll)假设有对象A,线程T

  • 是Object类的实例方法,且是native方法
  • T调用A的这些方法时必须先拥有A的对象锁,即只能在同步方法或同步块中调用这些方法。否则会抛出IllegalMonitorStateException(是RuntimeException故无需try catch)
  • 调用wait方法并不是立马释放锁,要等同步方法或同步块执行完;同理,调用notify、notifyAll并不会有线程立马获取到对象锁,需要等调用者所在同步方法或同步块执行完。
  • 可以理解为每个对象有个wait set(等待池)和monitor set(锁池)用来存放线程:wait set中线程等待收到通知信号(notify、notifyAll)、不会竞争获取A的对象锁,而monitor set中的线程则竞争对象锁;T调用A的wait方法则T进入wait set、T调用notify或notifyAll则wait set中的一个线程(随机选)或所有线程进入monitor set竞争对象锁。(从这可看出,第一个获得对象锁的wait线程执行完后,若没有继续调用该对象的notify或notifyAll,且monitor set中没有线程,则其他wait线程仍一直等待,即便对该对象锁已经空闲)

Java线程状态及 wait、sleep、join、interrupt、yield等的区别的更多相关文章

  1. Java线程状态Jstack线程状态BLOCKED/TIMED_WAITING/WAITING解释

    一.线程5种状态 新建状态(New) 新创建了一个线程对象. 就绪状态(Runnable) 线程对象创建后,其他线程调用了该对象的start()方法.该状态的线程位于可运行线程池中,变得可运行,等待获 ...

  2. Java线程状态、线程start方法源码、多线程、Java线程池、如何停止一个线程

    下面将依次介绍: 1. 线程状态.Java线程状态和线程池状态 2. start方法源码 3. 什么是线程池? 4. 线程池的工作原理和使用线程池的好处 5. ThreadPoolExecutor中的 ...

  3. 浅谈 Java线程状态转换及控制

    线程的状态(系统层面) 一个线程被创建后就进入了线程的生命周期.在线程的生命周期中,共包括新建(New).就绪(Runnable).运行(Running).阻塞(Blocked)和死亡(Dead)这五 ...

  4. Java线程状态及切换

    Java线程状态及切换 一.什么是Java线程状态 在Java程序中,用于描述Java线程的六种状态: 新建(NEW):当前线程,刚刚新建出来,尚未启动. 运行(RUNNABLE):当前线程,处于竞争 ...

  5. Java线程状态介绍

    原创:转载需注明原创地址 https://www.cnblogs.com/fanerwei222/p/11867086.html Java 线程状态介绍: Java官方文档中对Java线程的几种状态做 ...

  6. java线程中的sleep/wait/notify/yield/interrupt方法 整理

    java线程中的sleep/wait/notify/yield/interrupt方法 sleep 该方法能够使当前线程休眠一段时间 休眠期间,不释放锁 休眠时间结束之后,进入可执行状态,加入到线程就 ...

  7. Java线程状态转换

    前言:对于Java线程状态方面的知识点,笔者总感觉朦朦胧胧,趁着最近整理资料,将Java线程状态方面的知识点总结归纳,以便加深记忆. 1.Java线程状态值 在Thread类源码中通过枚举为线程定义了 ...

  8. Java线程状态切换以及核心方法

    1.Java线程状态 1.1 线程主要状态 ①初始(NEW):新创建了一个线程对象,但还没有调用start()方法.②运行(RUNNABLE):Java线程中将就绪(ready)和运行中(runnin ...

  9. 从源码看java线程状态

    关于java线程状态,网上查资料很混乱,有的说5种状态,有的说6种状态,初学者搞不清楚这个线程状态到底是怎么样的,今天我讲一下如何看源码去解决这个疑惑. 直接上代码: public class Thr ...

随机推荐

  1. Android应用一般上架流程

    Android App上架所需文件 上架准备  App文件: 1. 安装包 2. 应用商标:图片格式KB. 3. 应用截图(4~6张):图片格式JPG或者PNG.图片大小480*800,且每张大小一致 ...

  2. Android开发中无处不在的设计模式——动态代理模式

    继续更新设计模式系列.写这个模式的主要原因是近期看到了动态代理的代码. 先来回想一下前5个模式: - Android开发中无处不在的设计模式--单例模式 - Android开发中无处不在的设计模式-- ...

  3. Ubuntu 脚本笔记

    .Update Ubuntu :apt-get update :apt-get upgrade :apt-get dist-upgrade .Create swap on aliyun ubuntu( ...

  4. 两种屏幕HUD区域限制的做法(矩形,弧形)

    HUD区域限制算是比较常用到的功能,方形的HUD区域限制多见于小地图,弧形或者椭圆多见于屏幕范围约束. 我没有研究倒角矩形做法,而是将椭圆和矩形进行插值得到一个弧度比较高的形状: 当插值为0时限制范围 ...

  5. [nginx]编译安装及安全优化

    nginx配置-最后整理版 nginx_upstream_check_module nginx-module-vts nginx打补丁 nginx编译安装 - 下载 cd /usr/local/src ...

  6. 【Unity】11.4 车轮碰撞体(Wheel Collider)

    分类:Unity.C#.VS2015 创建日期:2016-05-02 一.简介 车轮碰撞体 (Wheel Collider)专门用于创建汽车或其他移动交通工具. 车轮碰撞体是一种针对地面车辆的特殊碰撞 ...

  7. (UML总结三)UML与软件project

    学习完UML.我们要把它和之前的软件project结合起来.软件project是从总体的角度说了软件开发的步骤.保证了所开发软件的质量.而UML作为一种统一建模语言.是用来设计软件蓝图的可视化建模语言 ...

  8. Java中创建String的两种方式差异

    我们知道创建一个String类型的变量一般有以下两种方法: String str1 = "abcd"; String str2 = new String("abcd&qu ...

  9. K-th string

    这两天参加了hihocoder上的小竞赛,下面把自己做的记录一下!(最痛心的是,开始竟然把main函数,写成了mian,浪费了将近一个小时时间,伤不起啊) Description Consider a ...

  10. 使用 CocoaPods 给微信集成 SDK 打印收发消息

    使用 CocoaPods 给微信集成 SDK 打印收发消息 推荐序 本文介绍的是一套逆向工具,可以在非越狱手机上给任意应用增加插件.在文末的示例中,作者拿微信举例,展示出在微信中打印收发消息的功能. ...