Java线程内部结构
我研究 Java 的内部原理已经有一段时间了。我很想了解和理解 Java 中的线程/锁定是如何发生的。
因此,为了访问同步方法或同步块,线程必须首先获取对象上的锁。所以,现在,我需要更多的光线。
那么,每当线程获取对象的锁时,它是否会在内部增加信号量的值? 如果答案是肯定的,那么让我们看一下这个场景。
class ABC{
public void method_1(){
synchronized(xyz){
....
}
}
public void method_2(){
...
synchronized(xyz){
....
}
}
}
因此,假设有两个线程:线程 1 和线程 2。假设线程 1 首先进入 method_1,因此首先获取了 xyz 上的锁。现在,Thread2 进入 method_2 并尝试获取 xyz 上的锁。会发生什么? (据我所知,Thread2 将被阻塞,因为它发现对象的信号量值>0)
让我知道我的推理是否正确。
I have been studying internals of Java for quite some time. I am curious to learn and understand how threading/locking takes place in Java.
So, in order to access a synchronized method or a synchronized block, the thread has to acquire the lock on the object first. So, now, here is what I need a bit more light.
So, whenever the thread acquires the lock on the object, does it increment the value of the semaphore internally?
If the answer is yes then let's take a look at this scenario.
class ABC{
public void method_1(){
synchronized(xyz){
....
}
}
public void method_2(){
...
synchronized(xyz){
....
}
}
}
So, say there are two threads: Threaad 1 and Thread 2. Assuming, Thread1 entered method_1 first and therefore acquired a lock on xyz first. And, say now, Thread2 enters method_2 and tries to acquire lock on xyz. What will happen?
(Acc to me, Thread2 will get blocked since it finds that the object's semaphore value>0)
Let me know if my reasoning is correct.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
特定于实现,但不太可能,因为每个锁只能获得一次,所以不需要计数器。一个简单的切换就可以了。我假设每个锁都保存对拥有它的线程的引用(或 null)。
更新:实际上,它比这要复杂得多。锁还需要维护一个正在等待它的线程列表。另外,线程可以通过等待/通知机制暂时释放锁(所以毕竟会有一个条目计数器)。最重要的是,锁管理对性能有很大影响,因此需要进行各种优化。我发现这个 有趣的博客,作者是从事 JVM 工作的人锁定。
是的,线程2将被阻塞,并等待它最终获得锁。
Implementation specific, but unlikely, Since every lock can be obtained only once, there is no need for a counter. A simple toggle will do. I assume that every lock holds a reference to the Thread that owns it (or null).
Update: Actually, it is quite a bit more complex than that. The lock also needs to maintain a list of threads that are waiting for it. Also, a thread can temporarily release a lock via the wait/notify mechanism (so there will be an entry counter after all). On top of that, lock management has a big impact on performance, so that there are all kinds of optimizations going on. I found this interesting blog by someone who is working on JVM locking.
Yes, Thread 2 will be blocked, and wait until it can eventually obtain the lock.
你的推理大致是正确的。线程 2 将被阻塞,并且将保持阻塞状态,直到(至少)线程 1 释放互斥锁。
然而,锁通常不使用带有简单计数器的传统信号量来实现。通常,如果对象被可重入锁定(例如,如果 Thread1 试图锁定 xyz,而它已经持有该对象的锁),或者当存在锁争用(例如,当 Thread2 尝试锁定
xyz
而 Thread1 已锁定它时)。但是您不需要关心 Java 锁的实现细节...除非您自己实现 JVM!
Your reasoning is roughly correct. Thread 2 will be blocked, and will remain blocked until (at least) Thread1 releases the mutex.
However, the lock is generally not implemented using a conventional semaphore with a simple counter. Typically there is a single lock bit that only gets "inflated" into a full lock if the object is locked reentrantly (e.g. if Thread1 tries to lock
xyz
while it already holds the lock on that object) or when there is contention for the lock (e.g. when Thread2 tries to lockxyz
while Thread1 has it locked).But you don't need to concern yourself with the implementation details of Java locks ... unless you are implementing a JVM yourself!
其他答案几乎回答了您的问题,但为了进一步阅读,我建议:
Java 并发实践
The other answers have pretty much answered your question, but for further reading I recommend:
Java Concurrency In Practice