繁体   English   中英

Java线程内部

[英]Java threads internals

我研究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,因此它将被阻塞)

让我知道我的推理是否正确。

每当线程获得对象上的锁时,它是否会在内部增加信号量的值?

特定于实现方式,但不太可能,因为每个锁只能获得一次,所以不需要计数器。 一个简单的切换即可。 我假设每个锁都拥有对拥有它的线程的引用(或为null)。

更新:实际上,这要复杂得多。 该锁还需要维护一个正在等待的线程列表。 另外,线程可以通过等待/通知机制临时释放锁(因此,毕竟会有一个入口计数器)。 最重要的是,锁管理对性能有很大影响,因此正在进行各种优化。 我发现了一个从事JVM锁定的人的有趣博客

因此,假设有两个线程:威胁1和线程2。假定线程1首先进入method_1,因此首先获得了对xyz的锁定。 并且,现在说,Thread2进入method_2并尝试获取对xyz的锁定。 会发生什么?

是的,线程2将被阻塞,并等待,直到最终获得该锁为止。

您的推理大致正确。 线程2将被阻塞,并且将保持阻塞状态,直到(至少)线程1释放互斥量为止。

但是,通常不使用带有简单计数器的常规信号量来实现锁定。 通常只有一个锁定位,如果该对象被可重入地锁定(例如,如果Thread1在该对象已经拥有该对象的锁定的情况下尝试锁定xyz )或存在对该锁定的争用(仅当锁定(例如,当Thread1锁定时Thread2尝试锁定xyz时)。

但是您不必担心Java锁的实现细节...除非您自己实现JVM!

其他答案几乎回答了您的问题,但建议进一步阅读: Java并发实践

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM