简体   繁体   English

两个线程如何进入两个锁定同一对象的同步块

[英]How can two threads enter two synchronized blocks which hold a lock on the same object

I have some code like this: 我有一些这样的代码:

public class HelloWorld {
    public static void main(String[] args){
        ThreadB b = new ThreadB();
        b.start();

        Runnable a = new Runnable(){
            public void run(){
                System.out.println(Thread.currentThread().getId());
                synchronized(b){
                    try{
                        System.out.println("Waiting for b to complete...");
                        b.wait();
                    }catch(InterruptedException e){
                        e.printStackTrace();
                    }
                    System.out.println("Total is: " + b.total);
                }
            }
        };

        (new Thread(a)).start();

        synchronized(b){
            System.out.println(Thread.currentThread().getId());
            try{
                System.out.println("Waiting for b to complete...");
                b.wait();
            }catch(InterruptedException e){
                e.printStackTrace();
            }

            System.out.println("Total is: " + b.total);
        }
    }
}

Class ThreadB: ThreadB类:

class ThreadB extends Thread{
    int total;
    @Override
    public void run(){
        synchronized(this){
            for(int i=0; i<100 ; i++){
                total += i;
            }
            System.out.println("Total is: " + total);
            notify();
        }
    }
}

Basically, I have two threads which lock on the Threadb object b. 基本上,我有两个线程锁定Threadb对象b。 When I run the code, I see: 运行代码时,我看到:

1
Waiting for b to complete... 
22
Waiting for b to complete...

Here, the numbers are the thread ids, so clearly, they are different threads. 在这里,数字是线程ID,因此很明显,它们是不同的线程。 Also, the object they are locking on is the same(b). 同样,他们锁定的对象是相同的(b)。 However, both are able to enter the synchronized block and wait on the object. 但是,两者都可以进入同步块并等待对象。

How's it possible? 怎么可能

Moreover, if I insert 2 other lines in the threadB.run() method: 此外,如果我在threadB.run()方法中插入其他2行:

class ThreadB extends Thread{
    int total;
    @Override
    public void run(){
        synchronized(this){
            for(int i=0; i<100 ; i++){
                total += i;
            }
            System.out.println("Total is: " + total);
            notify();
        }
    }
}

The 2 threads run to completion: 2个线程运行完毕:

Total is: 4950
22
1
Waiting for b to complete...
Waiting for b to complete...
Total is: 4950
Total is: 4950

It seems that in the older definition of ThreadB.run(), a notify signal was missed by the waiting threads, so they wait indefinitely. 似乎在较旧的ThreadB.run()定义中,等待线程错过了一个通知信号,因此它们无限期地等待。 Is it correct? 这是正确的吗?

Also, if a thread exits without calling notify(), the lock gets released intrinsically (equivalent to notifyAll()). 同样,如果线程退出而未调用notify(),则该锁将被内在释放(等效于notifyAll())。 Is that right? 那正确吗?

Because calling Object.wait() releases the lock. 因为调用Object.wait()会释放锁定。 From the documentation : 文档中

The current thread must own this object's monitor. 当前线程必须拥有该对象的监视器。 The thread releases ownership of this monitor and waits until another thread notifies threads waiting on this object's monitor to wake up either through a call to the notify method or the notifyAll method. 线程释放此监视器的所有权,并等待直到另一个线程通过调用notify方法或notifyAll方法通知等待在此对象监视器上等待的线程唤醒。 The thread then waits until it can re-obtain ownership of the monitor and resumes execution. 然后,线程等待,直到它可以重新获得监视器的所有权并恢复执行。

  1. It seems that in the older definition of ThreadB.run(), a notify signal was missed by the waiting threads, so they wait indefinitely. 似乎在较旧的ThreadB.run()定义中,等待线程错过了一个通知信号,因此它们无限期地等待。 Is it correct? 这是正确的吗? They wait() until they are notify() 'd (which can happen spuriously) or they are interrupted. 它们wait()直到被notify()终止(这可能是虚假的)或被中断。

  2. Also, if a thread exits without calling notify(), the lock gets released intrinsically (equivalent to notifyAll()). 同样,如果线程退出而未调用notify(),则该锁将被内在释放(等效于notifyAll())。 Is that right? 那正确吗? Once a thread is wait() ing, the lock is already released. 一旦线程正在wait() ,锁就已经释放。

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

相关问题 两个线程,两个同步块和一个内在锁 - Two threads, two synchronized blocks and one intrinsic lock 两个线程如何同时进入同步块? - How could the two threads enter the synchronized block at the same time? 两个线程如何一次锁定同一对象? - How two threads can take lock on same object at a time? 两个线程进入一个同步块 - Two threads enter a synchronized block 如何通过Junit测试两个线程无法同时访问的同步对象? - How to Junit test a synchronized object not accessed by two threads at same time? 两个线程如何“进入”“同步”方法 - How can two threads be “in” a “synchronized” method 如果两个线程使用不同的监视器,是否可以在同一个 object 上执行相同的同步代码块? - Can two threads execute the same synchronized block of code on the same object if they use different monitors? 可以使用两个嵌套的同步块来锁定数组的两个单元以进行原子操作吗? - Can one be using two nested synchronized blocks in order to lock two cells of an array for atomic operation? 两个线程可以同时访问同步方法吗? - Can two threads access a synchronized method at the same time? Java中的监视器和同步块(似乎两个线程同时拥有一个监视器) - Monitors and synchronized blocks in Java (it appears two threads own a monitor at the same time)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM