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. Tomcat7环境下面MySQL 56/Oracle数据库连接池的配置

    环境: Tomcat7 MySQL56 mysql-connector-java-3.1.10-bin.jar 步骤: 1. 配置context.xml 此文件位于~\tomcat7\conf目录下面 ...

  2. Atitit  404错误的排查流程总结 v3 qaf

    Atitit  404错误的排查流程总结 v3 qaf 1.1. 用了注解不生效 提示404 Not Found1 1.2. 路径不对了,开头多了个空格1 2. 500 Servlet Excepti ...

  3. 关于iPhone音频的那些事

    音频文件(Audio File) 1.有两个概念(1).文件格式(File Format or Audio Containers)——描述文件本身的格式,里面的音频数据可以用不同的编码格式.例如:ca ...

  4. 深入理解Linux内核-Ext2和Ext3文件系统

    Ext2的一般特征: 1.创建Ext2文件系统时,系统管理员可以根据预期的文件平均长度来选择最佳块大小(从1024B-4096B).来减少文件碎片2.创建Ext2文件系统时,系统管理员可以根据在给定大 ...

  5. 菜鸟学SSH(十三)——Spring容器IOC解析及简单实现

    最近一段时间,“容器”两个字一直萦绕在我的耳边,甚至是吃饭.睡觉的时候都在我脑子里蹦来蹦去的.随着这些天一次次的交流.讨论,对于容器的理解也逐渐加深.理论上的东西终归要落实到实践,今天就借助Sprin ...

  6. FFmpeg(10)-利用FFmpeg进行视频像素格式和尺寸的转换(sws_getCachedContext(), sws_scale())

    一.包含头文件和库文件 像素格式的相关函数包含在 libswscale.so 库中,CMakeLists需要做下列改动: # swscale add_library(swscale SHARED IM ...

  7. Linux系统Apache服务 - 配置 HTTP 的虚拟机主机

    接Linux系统Apache服务 - 配置HTTP的默认主页 1.创建/srv目录,作为httpd的文件目录,并创建/srv/default/www和/srv/www1.example.com/www ...

  8. 每日英语:Welcome to the Global Middle-Class Surge

    The mass uprisings this summer in Egypt, Turkey and Brazil are powerful reminders that the middle cl ...

  9. 每日英语:Why Mom's Time Is Different From Dad's Time

    Several years ago, while observing a parenting group in Minnesota, I was struck by a confession one ...

  10. 【MySQL】MySQL在CentOS的搭建

    安装mysql 查询yum服务器上可用的关于mysql的安装包: [root@localhost ~]# yum list | grep mysql mysql-libs.x86_64 5.1.71- ...