首页 > 编程知识 正文

java多线程wait唤醒后是什么状态,java线程死锁是什么原因引起

时间:2023-05-05 00:47:58 阅读:179679 作者:3400

使用Java块I/O模型读取数据时,线程将阻塞,线程将进入休眠状态,并释放CPU的执行权限,直到数据读取完成。 在此期间使用jstack查看线程的状态,可以看到Java线程的状态为RUNNABLE。 这与上述内容相矛盾。 为什么会这样呢?

上述矛盾之处在于,它混淆了操作系统线程的状态和Java线程的状态。 这里的线程阻塞并进入休眠状态,实际上是OS级别的线程的实际情况。 使用jstack查看的线程状态是JVM线程的状态。

线程是操作系统中的概念,由Java封装。 Java线程本质上是操作系统中的线程,其状态与操作系统的状态几乎相同,但存在一些差异。

首先来看看我们熟悉的Java线程的状态。

Java线程状态Java线程的状态在Thread.State枚举中定义,可以使用thread#getState方法获取当前线程的状态。

Thread.State的状态如下图所示。

在State.png中,您可以看到Java线程总共有六个状态。 分别如下。

NEW (初始状态)

运行状态

阻塞)。

等待)

TIMED_WAITING (等待超时状态) )

已终止)

NEW(初始状态)与 RUNNABLE(运行状态)

使用new Thread ()创建线程实例时(状态为NEW,thread.start ) ),线程的状态为http://www.Sina.com

RUNNABLE

具有3358www.Sina.com/状态的线程在进入synchronized限定的方法或代码块之前会尝试获取隐式独占锁。 如果无法获取,则线程状态为RUNNABLE(运行状态) 与 BLOCKED(阻塞状态),等待获取锁。 如果其他线程解锁,并且线程成功获得锁定,则线程的状态将从RUNNABLE更改为BLOCKED的状态。

BLOCKED

处于RUNNABLE状态的线程将处于无限等待状态,并且必须等待其他线程唤醒。 共有三种方法可以将线程从RUNNABLE(运行状态) 与 WATTING(等待状态)更改为WATTING

对象#等待

调用Object#wait (方法),在线程获得同步隐式锁定后显示。 在这种情况下,线程将释放隐式锁定。 当其他线程获取锁并调用Object.notify (或object.notifyAll ) )时,该线程将唤醒并变为RUNNABLE

Thread#join

join方法是线程同步方法。 在main方法中执行Thread A.join ()方法时,main线程的状态为WATTING。 在a线程运行之前,主线程必须位于RUNNABLE

LockSupport#park (

LockSupport是JDK和建设中的重要对象,许多锁的实现都依赖于此对象。 调用LockSupport#park ()会将线程置于WATTING状态。 如果需要启动线程,请调用LockSupport#unpark以将线程状态设置为RUNNABLE

WATTING

3358www.Sina.com/与RUNNABLE的功能相同,但前者增加了超时功能,超时后线程状态自动变为RUNNABLE(运行状态) 与 TIMED_WAITING(限时等待状态)以下情况会导致这种情况:

趋势#速度(长时间)

占用同步隐式锁的线程调用object.wait(longtimeout )方法

thread#join(longmillis ) ) ) ) ) ) ) ) ) ) ) ) )。

lock support # park nanos (object blocker,long deadline ) )。

lock support # park until (long deadline ) )。

p>

RUNNABLE(运行状态)与 TERMINATED(终止状态)

线程一旦执行结束或者线程执行过程发生异常且未正常捕获处理,状态都将会自动变成 TERMINATED

Java 线程 6 种状态看起来挺复杂的,但其实上面 BLOCKEDWATTINGTIMED_WAITING,都会使线程处于休眠状态,所以我们将这三类都归类为休眠状态。这么分类的话,Java 线程生命周期就可以简化为下图:

java线程状态2.png 通用操作系统线程状态

上面讲完 Java 系统的线程状态,我们来看下通用操作系统的线程状态。操作系统线程状态可以分为初始状态,可运行状态,运行状态,休眠状态以及终止状态,如下图:

操作系统线程状态1.png

这 5 中状态详细情况如下:

初始状态,这时候线程刚被创建,还不能分配 CPU 。

可运行状态,线程等待系统分配 CPU ,从而执行任务。

运行状态,操作系统将 CPU 分配给线程,线程执行任务。

休眠状态,运行状态下的线程如果调用阻塞 API,如阻塞方式读取文件, 线程状态就将变成休眠状态。这种情况下,线程将会让出 CPU 使用权。休眠结束,线程状态将会先变成可运行状态。

线程执行结束或者执行过程发生异常将会使线程进入终止状态,这个状态下线程使命已经结束。

对比两者线程状态

比较 Java 线程与操作系统线程,可以发现 Java 线程状态没有可运行状态。也就是说 Java 线程 RUNNABLE 状态包括了操作系统的可运行状态与运行状态。一个处于  RUNNABLE 状态 Java 线程,在操作系统层面状态可能为可运行状态,正在等待系统分配 CPU 使用权。

另外 Java 线程细分了操作系统休眠状态,分成了 BLOCKEDWATTINGTIMED_WAITING 三种。

当线程调用阻塞式 API,线程进入休眠状态,这里指的是操作系统层面的。从 JVM 层面,Java 线程状态依然处于 RUNNABLE 状态。JVM 并不关心操作系统线程实际状态。从 JVM 看来等待 CPU 使用权(操作系统线程状态为可运行状态)与等待 I/O (操作系统线程状态处于休眠状态)没有区别,都是在等待某种资源,所以都归入 RUNNABLE 状态。

其他 Java 线程状态与操作线程状态类似。

欢迎加入我们的知识星球,一起成长,交流经验。加入方式,长按下方二维码噢

最后,我想重复一句话:选择和一群优秀的人一起成长,你成长的速度绝对会不一样!

欢迎转发到朋友圈

欢迎留言    

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。