您在采访中可能已经遇到过这个问题,锁和监视器之间有什么区别?好吧,要回答这个问题,您必须对Java多线程如何在后台工作有足够的了解。
答案很简短,锁为实现监视器提供了必要的支持。长答案在下面阅读。
lock
锁是一种数据,在逻辑上是堆内存上对象标头的一部分。JVM中的每个对象都具有此锁(或互斥锁),任何程序均可使用该锁来协调对对象的多线程访问。如果有任何线程想要访问该对象的实例变量;然后线程必须“拥有”对象的锁(在锁存储区中设置一些标志)。试图访问该对象变量的所有其他线程必须等待,直到拥有该线程的线程释放该对象的锁(取消设置标志)。
线程拥有锁后,它可以多次请求相同的锁,但是在将锁提供给其他线程之前,必须释放相同的次数。例如,如果一个线程请求了三次锁,则该线程将继续拥有该锁,直到它“释放”了三次。
请注意,当线程明确要求锁时,它是由线程获得的。在Java中,这是通过synced关键字或通过waitand来完成的notify。
monitor
Monitor是一种同步构造,它允许线程具有互斥(使用锁)和协作功能,即使线程能够等待某些条件成立(使用wait-set)的能力。
换句话说,连同实现锁的数据,每个Java对象在逻辑上均与实现a的数据相关联wait-set。锁可以帮助线程在共享数据上独立工作而不会互相干扰,而等待集帮助线程可以相互协作以共同朝着一个共同的目标努力,例如,所有等待线程都将移至该等待集,并通知所有一旦锁定被释放。此等待集通过锁定(mutex)的其他帮助来帮助构建监视器。
Mutual exclusion
用简单的话来说,监视器就像一栋建筑物,其中包含一个特殊的房间(对象实例),一次只能占用一个线程。房间中通常包含一些需要防止并发访问的数据。从线程进入该房间的时间到它离开的时间,它都可以独占访问该房间中的任何数据。进入显示器大楼称为“进入显示器”。进入建筑物内的特殊房间称为“获取显示器”。占领房间称为“拥有显示器”,离开房间称为“释放显示器”。离开整个建筑物称为“退出监视器”。
当线程到达以访问受保护的数据(进入特殊房间)时,首先将其放入建筑物接收队列中(条目集)。如果没有其他线程在等待(监视器拥有),则该线程获取锁并继续执行受保护的代码。线程完成执行后,它将释放锁并退出建筑物(退出监视器)。
如果一个线程到达并且另一个线程已经拥有监视器,则它必须在接收队列中等待(条目集)。当前所有者退出监视器时,新到达的线程必须与也在入口集中等待的任何其他线程竞争。只有一个线程会赢得比赛并拥有锁。
等待设置功能没有作用。
Cooperation
通常,互斥仅在多个线程共享数据或其他资源时才重要。如果两个线程不使用任何公共数据或资源,则它们通常不会相互干扰,也不必以互斥的方式执行。互斥有助于防止线程在共享数据时相互干扰,而协作则可以帮助线程一起朝着某个共同的目标努力。
当一个线程需要某些数据处于特定状态,而另一个线程负责使数据进入该状态时,合作非常重要,例如生产者/消费者问题,其中读取线程需要缓冲区处于“非空”状态才可以从缓冲区读取任何数据。如果读取线程发现缓冲区为空,则必须等待。写线程负责用数据填充缓冲区。一旦写入线程完成了更多写入操作,读取线程便可以进行更多读取操作。有时也称为“ 等待并通知 ”或“ 发出信号并继续””监视器,因为它保留了监视器的所有权,并在需要时继续执行监视器区域(继续)。在稍后的某个时间,通知线程释放监视器,并且等待线程恢复拥有该锁。
这种合作需要进入集和等待集。下面给出的图将帮助您理解这种合作。
上图将监视器显示为三个矩形。在中心,一个大矩形包含一个线程,即监视器的所有者。在左侧,一个小矩形包含条目集。在右侧,另一个小矩形包含等待集。
我希望以上讨论将有助于您获得更多见识。免费免费问任何问题。
学习愉快!