简体   繁体   English

java同步和对象锁

[英]java synchronize and object lock

Suppose I have two threads. 假设我有两个线程。 Thread1 is accessing a synchronized method, and at the same time, Thread2 is accessing another synchronized method of the same object. Thread1正在访问同步方法,同时,Thread2正在访问同一对象的另一个同步方法。 As what I know, Thread2 should wait till Thread1 finish its task. 据我所知,Thread2应该等到Thread1完成它的任务。 My question is, is Thread2 on the object's waiting thread list? 我的问题是,对象的等待线程列表上是否有Thread2? It seems so for me, but Thread2 doesn't call wait() method, then as a logic result, it shouldn't on the object's waiting thread list. 对我来说似乎是这样,但是Thread2不会调用wait()方法,然后作为逻辑结果,它不应该在对象的等待线程列表上。 If it's not on the object's waiting thread list, what's the status of Thread2? 如果它不在对象的等待线程列表中,那么Thread2的状态是什么?

When Tread2 is waiting for Thread1 to release the intrinsic lock held by Thread1, its blocked until the intrinsic lock becomes available (as in, u released by the executing thread, Thread1). 当Tread2等待Thread1释放Thread1持有的内部锁时,它会被阻塞,直到本机锁变为可用(如执行线程Thread1释放的那样)。 So, in summery, Thread2 is waiting for the lock to be released, so it can acquire it. 因此,在夏天,Thread2正在等待释放锁,因此它可以获取它。

Now, when a thread calls wait() , it must already hold the intrinsic lock . 现在,当一个线程调用wait()它必须已经拥有内部锁 A call to wait() then releases the lock , and puts the thread in a waiting state, where its waiting for a signal from notify() or a notifyAll() to continue execution. wait()调用然后释放锁 ,并将线程置于等待状态,等待来自notify()notifyAll()的信号继续执行。

So, the two scenarios are different, the former is about execution implicitly being blocked until resource(the lock) becomes available. 因此,这两种情况是不同的,前者是关于执行隐式地被阻止,直到资源(锁)变得可用。 While the later is about explicitly releasing the a already held lock, and then waiting for a signal that its time to re-acquire the lock and continue. 虽然后者是关于明确释放已经保持的锁定,然后等待其时间重新获取锁定并继续的信号。

There is a distinction between those two scenarios, as you are right to note. 这两种情况之间存在差异,因为您需要注意。

When a thread tries to run a synchronized block, but some other thread holds the monitor's lock, the incoming thread is blocked , until the lock is released, and granted to it. 当一个线程试图运行一个synchronized块,但是其他一些线程持有监视器的锁时,传入的线程被阻塞 ,直到锁被释放并被授予它。

For a thread to call wait() , it must already hold the monitor's lock (this is a relevant difference). 对于调用wait()的线程,它必须已经保持监视器的锁定(这是一个相关的区别)。 Besides, calling wait() puts the thread waiting (releasing the lock), usually until it is notified by some other thread. 此外,调用wait()会使线程等待 (释放锁定),通常直到其他线程通知它为止。

The usually above should be always , in an ideal scenario, but, as specified in the Java documentation, a phenomenon called spurious wakeup may occur, making the waiting thread wake up for no apparent reason . 在理想情况下, 通常上面应该总是如此 ,但是,如Java文档中所指出的,可能会出现称为虚假唤醒的现象,使得等待线程无缘无故地唤醒。 That's why the waiting conditions should be enclosed in a while statement, instead of an if . 这就是为什么等待条件应该用while语句括起来,而不是if Example: 例:

synchronized (this) {
    while (x < 0) { wait(); }
}

Instead of: 代替:

synchronized (this) {
    if (x < 0) { wait(); }
}

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

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