以下代码中使用关键字synchronized的意义

Significance of use of keyword synchronized in the following code

我正在阅读 Java The Complete Reference by Herbert Schildt 一书的 Java 中的 multi threading。我遇到了以下代码 [Pg. 252,第 7 版。] 解释了现代 Javawait()notify()suspendresume 线程的用法。我的问题是关于关键字 synchronization 在以下代码中两个地方的重要性(在 class NewThreadrun() 方法中):

// Suspending and resuming a thread the modern way.
class NewThread implements Runnable {
    String name;
    Thread t;
    boolean suspendFlag;
    NewThread(String threadname) {
        name = threadname;
        t = new Thread(this, name);
        suspendFlag = false;
        t.start();
    }
// This is the entry point for thread.
    public void run() {
        try {
            for (int i = 15; i > 0; i--) {
                System.out.println(name + ": " + i);
                Thread.sleep(200);
                synchronized (this) { //First doubt here
                    while (suspendFlag) {
                        wait();
                    }
                }
            }
        } catch (InterruptedException e) {
            System.out.println(name + " interrupted.");
        }
        System.out.println(name + " exiting.");
    }
    void mysuspend() {
        suspendFlag = true;
    }
    synchronized void myresume() { //Second doubt here
        suspendFlag = false;
        notify();
    }
}

class SuspendResume {
    public static void main(String args[]) {
        NewThread ob1 = new NewThread("One");
        NewThread ob2 = new NewThread("Two");
        try {
            Thread.sleep(1000);
            ob1.mysuspend();
            Thread.sleep(1000);
            ob1.myresume();
            ob2.mysuspend();
            Thread.sleep(1000);
            ob2.myresume();
        } catch (InterruptedException e) {
            System.out.println("Main thread Interrupted");
        }
        //some code
}

我的疑问:我知道关键字synchronization的用法,即只允许一个线程进入同一个对象的同步方法,但这里我们有两个线程 运行 在两个不同的对象上。那么上面代码中使用的两个 synchronization 关键字的意义是什么。

我尝试 运行 上面的代码,通过在每个地方以不同方式同时删除 synchronized 关键字。我收到相同的错误:java.lang.IllegalMonitorStateException: current thread is not owner 不同的次数和不同的行号,具体取决于我是同时删除还是只删除一个(以及哪个)synchronization 关键字。我查找了上述错误并找到了解释 here 但仍然无法将答案与我的疑问联系起来。

synchronized解决的问题是,它允许两个线程对共享的suspendFlag变量有一致的看法。

在某些实际程序中,线程可能会在设置 susependFlag=false 之前设置其他共享变量。如果未使用 synchronized,则等待线程可以唤醒,并看到 suspendFlag==false,但 不会 看到其他变量集。或者更糟的是,它可以看到其中一些设置,但看不到其他设置。

没有同步,Java 不能保证不同的线程会看到变量以相同的顺序更新。

I am getting the same error: java.lang.IllegalMonitorStateException: current thread is not owner.

Java 库试图通过强制 你使用 synchronized 来帮助你,然后它才允许你使用 wait()notify()。规则很简单:您只能从 synchronized(o) 块内的代码调用 o.wait()o.notify()o.notifyAll()。如果您违反该规则,则库会抛出异常。

当您的代码调用 o.wait() 时,wait() 临时调用 解锁 监视器锁,以便其他线程能够在 o 上同步并致电 o.notify()o.wait() 调用保证在 returns.

之前调用 re-lock o