Java线程内部

时间:2010-02-21 06:15:21

标签: java multithreading locking semaphore synchronized

我已经研究了Java内部很长一段时间了。我很想学习并理解Java中的线程/锁定是如何发生的。

因此,为了访问同步方法或同步块,线程必须首先获取对象的锁定。那么,现在,我需要更多的光。

因此,每当线程获取对象的锁定时,它是否在内部增加信号量的值? 如果答案是肯定的,那么让我们来看看这个场景。

class ABC{ 

    public void method_1(){
        synchronized(xyz){
            ....
        }
    }

    public void method_2(){
        ...
        synchronized(xyz){
            ....
        }
    }
}

所以,假设有两个线程:Threaad 1和Thread 2.假设, Thread1 首先输入method_1,因此首先获得了对xyz的锁定。而且,现在说, Thread2 进入method_2并尝试获取xyz上的锁定。会发生什么? (对我来说,Thread2会被阻止,因为它发现对象的信号量值> 0)

如果我的推理是正确的,请告诉我。

3 个答案:

答案 0 :(得分:1)

  

每当线程获取对象的锁定时,它是否在内部递增信号量的值?

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

更新:实际上,它比这复杂得多。锁还需要维护一个等待它的线程列表。此外,线程可以通过等待/通知机制暂时释放锁(因此毕竟会有一个输入计数器)。最重要的是,锁管理对性能有很大影响,因此存在各种优化。我发现这个interesting blog是由正在进行JVM锁定的人发现的。{/ p>

  

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

是的,线程2将被阻止,并等到它最终可以获得锁定。

答案 1 :(得分:1)

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

然而,通常不使用具有简单计数器的传统信号量来实现锁定。通常,如果对象被重新锁定(例如,如果Thread1在已经保持对该对象的锁定时尝试锁定xyz)或存在争用时,则只有一个锁定位才会“膨胀”为完全锁定用于锁定(例如,当Thread1将其锁定时,Thread2尝试锁定xyz)。

但是你不需要关心Java锁的实现细节......除非你自己实现JVM!

答案 2 :(得分:1)

其他答案几乎已经回答了你的问题,但为了进一步阅读,我建议: Java Concurrency In Practice