java—线程、锁和条件的状态

llycmphe  于 2021-07-12  发布在  Java
关注(0)|答案(2)|浏览(327)

关闭。这个问题需要更加突出重点。它目前不接受答案。
**想改进这个问题吗?**通过编辑这篇文章更新这个问题,使它只关注一个问题。

三年前关门了。
改进这个问题
在java中,如果线程, t2 ,尝试从synchronized获取另一个线程当前正在使用的锁, t1 ,那么 t2 将从runnable切换到blocked。对的?你觉得呢 ReentrantLock 什么?
如果线程 t1 把锁用完了,是吗 t2 然后自动切换回runnable或者您需要使用 notifyAll() ? 你觉得呢 ReentrantLock 无条件使用。如果不使用条件,如何通知线程 t2 它应该切换回runnable吗?使用无条件重入锁是否明智,甚至可能?
如果这个问题已经被回答了(我找不到),如果你能把它和我联系起来,我将不胜感激。

lpwwtiir

lpwwtiir1#

听起来你把阻塞状态和等待状态搞混了。阻塞意味着线程正在尝试获取锁,因此无法获取,因此被卡住。等待意味着线程处于休眠状态;它一直挂起,直到它收到通知,或者直到它从等待中返回(超时,如果用超时值调用,或者伪唤醒)。
一旦一个锁可用,操作系统调度程序就必须决定哪个被阻塞的线程获得它。它为获取锁而选择的线程将变为可运行。
所以notify属于等待线程,而不是阻塞线程。一个线程拥有锁,但是发现它不能前进(它检测到它等待的条件不是真的)可以调用该锁上的wait,释放锁并进入休眠状态。使用notify通知调度程序唤醒正在等待锁的任何一个线程。一旦线程被唤醒,它必须重新获得它之前释放的锁,然后才能退出wait方法。
可重入锁的基本行为类似于内在锁,不同的是,可重入锁可以有多个条件。请记住,reentrantlock有自己单独的调用方法(await和signal,而不是wait和notify)。当您希望线程等待并得到通知时,您可以使用reentrantlock的条件,使用不同的条件,以便线程只在与它们相关的条件下等待。

nc1teljy

nc1teljy2#

如果一个线程t2尝试在另一个线程t1当前正在使用的锁上进行同步(例如,当t1已经在同一个锁的同步块中时,尝试进入同步块),那么t2将阻塞,yes。可重入锁也是如此,包括 ReentrantLock 班级;需要注意的是,默认锁在java中是可重入的(稍后将对此进行详细介绍)。
如果t1释放一个默认锁,例如通过退出同步块,那么t2被解锁;这是语言的一个特点。但是,如果您使用的是可重入锁,则持有该锁的线程必须显式调用 ReentrantLock.unlock() 释放锁,就像它所说的那样 ReentrantLock.lock() 获得锁。
注意,“可重入”是指单个线程是否可以“重入”同步块,而不是指线程之间的任何交互。可重入锁可以被已经持有锁的线程再次锁定;不能使用非进入锁。注意,在java中,如果一个线程多次获得可重入锁,那么它必须在其他等待该锁的线程解除阻塞之前释放相同次数的锁。对于默认锁,嵌套的同步块自然会发生这种情况,可能是在不同的函数调用级别。

相关问题