Java中的监视器和同步块(看起来两个线程同时拥有一个监视器)

Fuh*_*tor 2 java multithreading synchronized notify wait

我试图理解synchronized()我在本文末尾写的程序中的块.

有两个线程(ok)使用共享lock对象作为wait/notify的监视器.

ok在以下synchronized块中等待启动:

synchronized (lock) {
    lock.wait(); // wait for K to be ready
}
Run Code Online (Sandbox Code Playgroud)

k然后通知o并等待它在这个块内打印:

synchronized (lock) {
    lock.notify(); // tell O to print
    lock.wait(); // wait for O to print
}
Run Code Online (Sandbox Code Playgroud)

我的问题是如何k进入同步块lock?不应该o拥有lock(因为它被称为wait())?在Java教程说:

只要一个线程拥有一个内部锁,没有其他线程可以获得相同的锁.另一个线程在尝试获取锁时将阻塞.

这是完整的程序:

public class OK implements Runnable {

    private static final Object lock = new Object(); // monitor for wait/notify

    private boolean isO;

    public OK(boolean b) {
        isO = b;
    }

    public static void main(String[] args) throws InterruptedException {

        Thread o = new Thread(new OK(true));
        Thread k = new Thread(new OK(false));
        o.start();
        k.start();
        k.join(); // when k is done, we're done
        System.out.println("Done.");

    }

    public void run() {

        // run method is called for both o and k, so we separate the logic
        try {
            if (isO) {
                doO();
            } else {
                doK();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

    // O thread logic
    private void doO() throws InterruptedException {

        // K needs to be ready before I start
        synchronized (lock) {
            lock.wait(); // wait for K to be ready
        }

        System.out.print("O");
        synchronized (lock) {
            lock.notify(); // tell K I printed
        }
    }

    // K thread logic
    private void doK() throws InterruptedException {

        // O is waiting for me to start

        synchronized (lock) {
            lock.notify(); // tell O to print
            lock.wait(); // wait for O to print
        }
        System.out.println("K");
    }

}
Run Code Online (Sandbox Code Playgroud)

Wou*_*rts 5

lock.wait释放监视器.请参阅Object.wait()javadoc:

当前线程必须拥有此对象的监视器.线程释放此监视器的所有权并等待,直到另一个线程通过调用notify方法或notifyAll方法通知等待此对象监视器的线程唤醒.然后线程等待,直到它可以重新获得监视器的所有权并继续执行.

直觉可能会告诉你"同步(锁定)"意味着它在它包装的整个块中保持锁定; 但这不是它的工作原理.