Java线程在等待期间无法获取锁是啥状态

     2023-03-15     142

关键词:

【中文标题】Java线程在等待期间无法获取锁是啥状态【英文标题】:What is the state of Java thread during waiting and unable to obtain lockJava线程在等待期间无法获取锁是什么状态 【发布时间】:2016-04-26 21:23:25 【问题描述】:

Java 线程可以被以下任一者持有:

    无法获得锁。 被 wait() 方法持有。

以上两种场景在Java线程状态方面有什么区别?

考虑以下简单代码:

   synchronized(object) 
       object.wait();
       System.out.println("Completed.");
   

如果两个线程(比如 ThreadA 和 ThreadB)都在 wait() 方法中。例如,当另一个线程调用 notifyAll() 时,ThreadA 将从等待中恢复并获得对象上的锁定并继续。 ThreadB 也将恢复,但无法获得对象上的锁定并被持有,直到 ThreadA 退出同步块。 ThreadB 然后获得锁并继续。

结果将打印两个“已完成”。

在这个例子中,一定有一段时间 ThreadB 从“被 wait() 持有”变为“因为无法获得对象的锁而被持有”。

我想知道它在 Java 内部是如何工作的。请帮忙。

【问题讨论】:

基于enum Thread.State 的Javadoc(我没有尝试过实验),状态应该从WAITING 更改为BLOCKED。也许你可以做个实验,看看我说的对不对。 这个answer已经非常详细地解释了所有等待线程在收到通知后的行为。 【参考方案1】:

处于object.wait()状态和等待object的monitor上锁的区别在于object.wait()状态的线程释放它所持有的所有object的monitor,它将与所有的系统中的线程再次重新获取监视器。这使得wait() 成为一个特殊的状态。

因此,在您的情况下,当AB(线程A 和线程B)处于等待状态时,它们没有同步监视器object,它们都已暂停执行直到某个时间其他线程调用object.notify()object.notifyAll()。当notifyAll() 被调用时,JVM 会唤醒所有处于object.wait() 状态的线程(在本例中为AB),它们会竞争以获取当前synchronized 块的监视器。如果 notify() 被调用,那么 JVM 会随机选择 A 或 B。

这里要注意的是,JVM 没有通知任何特定线程,这就是为什么每个等待线程都必须在 while(notify_condition_for_me) 循环中等待的原因,这会验证等待条件是否已经存在,如果不是则必须进入 @ 987654338@再次状态。

所以正确的代码应该是

synchronized(object) 
   while(myResourceArrived) //like URL data, JDBC data or something
       object.wait();
   
   System.out.println("Completed.");

AB 处于object.wait() 状态时,它们已经释放了之前为object 持有的所有监视器,因此在synchronized 块外等待的任何其他线程将立即能够获取object的释放监视器进入区块。

【讨论】:

【参考方案2】:

查看Thread.State,更具体地说是WAITINGBLOCKED 状态。

如果您对内部实现感兴趣,两者都可以使用LockSupport.park()LockSupport.unpark(Thread) 来实现,实际上大多数地方都是这样实现的。

附:如果您有兴趣,这里是 Windows (line 4946) 和 Linux (line 5808) 的 OpenJDK park() 实现,这里是 wait()/notify()/notifyAll() 实现(第 1457 行)。他们的评论很好,如果第一眼看起来太复杂,请给它一些时间。

【讨论】:

请问java中的lock和synchronized区别是啥?

...内存语义,此外还多了锁投票,定时锁等候和中断锁等候线程A和B都要获取对象O的锁定,假设A获取了对象O锁,B将等待A释放对O的锁定,如果使用synchronized,如果A不释放,B将一直等下去,不能被中断如果使用ReentrantLock,如果A不... 查看详情

java多线程系列--“juc锁”05之非公平锁

...是空闲的,即可获取状态,则获取锁)。在前面的“Java多线程系列--“JUC锁”03之 查看详情

java深入学习11:lock锁详解(代码片段)

...chronized关键字更广泛的锁操作,它能以更优雅的方式处理线程同步问题。也就是说,Lock提供了比synchronized更多的功能。二、代码分析1-Lock类方法说明publicinterfaceLock//获取锁方式1:最常用的方式。如果当前锁不可用,当前线程无... 查看详情

自旋锁(spinlock)

...的对象引用变量。原子意味着尝试更改AtomicReference的多个线程(例如:比较和交换操作),不会是AtomicReference最终达到不一致的效果。        AtomicReference有一个先进的方法compareAndSet(),它可以将引用... 查看详情

线程系列--浅说高层并发

...eentrantLockpublicinterfaceLock//用来获取锁。如果锁是不可用则线程等待直到获取到锁。voidlock();/**//如果当前线程没有被中断获取锁。//如果锁是可用的,请求锁并马上返回;如果锁不可用,当前线程就不能完成线程调度&#x... 查看详情

java多线程的几种状态

java线程状态在Thread中定义,源码中能看到有个枚举State,总共定义了六种状态:NEW:新建状态,线程对象已经创建,但尚未启动RUNNABLE:就绪状态,可运行状态,调用了线程的start方法,已经在java虚拟机中执行,等待获取操作系统... 查看详情

java中wait方法是啥意思

...zed块中。一般在判断语句中,如果某条件被触发,让当前线程wait并释放对象的锁。此时可以让其他线程可以对用以对象调用synchronized方法。直到调用notify或者notifyAll后wait的线程才有可能执行。所以一般wait和notify是成对出现的。... 查看详情

java线程

一、线程状态与生命周期    二、阻塞状态如果一个线程执行了sleep(睡眠)、suspend(挂起)等方法,失去所占用资源之后,该线程就从运行状态进入阻塞状态。在睡眠时间已到或获得设备资源后可以重新进入就绪... 查看详情

怎样分析java的threaddumps

当看到线程栈的log的时候,第一反应是以下几个threadstate线程状态为"waitingformonitorentry"意味着它在等待进入一个临界区,所以它在”EntrySet“队列中等待。此时线程状态一般都是Blocked:java.lang.Thread.State:BLOCKED(onobjectmonitor)... 查看详情

面试java基础锁

...态只能升级不能降级。无锁没有锁对资源进行锁定,所有线程都能访问并修改同一个资源,但同时只有一个线程能修改成功。其他修改失败的线程会不断重试,直到修改成功,如CAS原理和应用是无锁的实现。偏向锁偏向锁是指一... 查看详情

lock的两种方式

假设现在我们有100个数据项可以读写。有若干个线程,任何一个线程可能对任何一个数据项尽心读写。但是,如果不同的线程在对同一个数据项进行读写,就可能发生错误。需要使用lock进行控制。比如线程x要对数据项50进行写... 查看详情

aqs(代码片段)

...QS的实现依赖内部的同步队列(FIFO双向队列),如果当前线程获取同步状态失败,AQS会将该线程以及等待状态等信息构造成一个Node,将其加入同步队列的尾部,同时阻塞当前线程,当同步状态释放时,唤醒队列的头节点。AQS最... 查看详情

线程的状态

六种:1、新建(New):创建后尚未启动的线程的状态 2、运行(Runnable):包含Running和Ready 3、无限期等待(Waiting):不会被分配CPU执行时间,需要显式被唤醒没有设置Timeout参数的Object.wait()方法没有设置Timeout参数的Thread.join(... 查看详情

java线程状态及转换

java线程有6种状态:新建线程new,启动线程runnable,阻塞block,限时等待timed_waiting,等待线程waiting,终止线程terminated1.限时等待timedwaiting:处于这种状态的线程不会被分配cpu执行时间。不过无须等待被其他线程显式地唤醒,在一定时间... 查看详情

Java 线程中的“阻塞计数”和“等待计数”是啥意思?

】Java线程中的“阻塞计数”和“等待计数”是啥意思?【英文标题】:Whatdoes"blocked Count"and"WaitedCount"inaJavaThreadmean?Java线程中的“阻塞计数”和“等待计数”是什么意思?【发布时间】:2011-08-2403:53:06【问题描述... 查看详情

java并发(代码片段)

一、线程状态转换新建(New)创建后尚未启动。可运行(Runnable)可能正在运行,也可能正在等待CPU时间片。包含了操作系统线程状态中的Running和Ready。阻塞(Blocking)等待获取一个排他锁,如果其... 查看详情

线程的状态

Java线程在运行的生命周期中可能处于表4-1所示的6种不同的状态,在给定的一个时刻,线程只能处于其中的一个状态。表4-1Java线程的状态   图4-1Java线程状态变迁由图4-1中可以看到,线程创建之后,调用start()方法开始... 查看详情

线程啥时候会报interruptedexception

...160;方法3.java.lang.Thread类的 join 方法执行wait方法的线程,会进入等待区等待被notify/notifyAll。在等待期间,线程不会活动。执行sleep方法的线程,会暂停执行参数内所设置的时间。执行join方法的线程,会等待到指定的线程... 查看详情