java IllegalMonitorStateException notify() 和 wait()

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14234619/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 15:33:21  来源:igfitidea点击:

IllegalMonitorStateException notify() and wait()

javawaitnotifyillegalmonitorstateexcep

提问by Sylwek

I have a problem. When I use notify()in synchronized block I have IllegalMonitorStateException. Can anyone help me to solve this problem?

我有个问题。当我notify()在同步块中使用时,我有 IllegalMonitorStateException。谁能帮我解决这个问题?

I have to do that, one thread will send to second thread char, then this thread has to wait and second thread print this char. After that second thread wait, and first one again send next char

我必须这样做,一个线程将发送到第二个线程字符,然后这个线程必须等待第二个线程打印这个字符。在第二个线程等待之后,第一个再次发送下一个字符

Main.java:

主.java:

import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JOptionPane;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
public class Main extends JFrame {

    Thread t1, t2;
    Consumer con;

    public Main() {
        con = new Consumer();
        startThreads();
    }

    private synchronized void startThreads() {
        t1 = new Thread(new Producent("grudzien", con));
        t1.start();
        t2 = new Thread(con);
        t2.start();
    }

    public class Producent implements Runnable {

        String m_atom;
        char[] atoms;
        Consumer m_c;

        public Producent(String atom, Consumer c) {
            m_atom = atom;
            m_c = c;
        }

        @Override
        public void run() {
            synchronized (this) {
                atoms = m_atom.toCharArray();
                System.out.print("Tablica znaków: ");
                for (int i = 0; i < atoms.length; i++) {
                    System.out.print(atoms[i] + ", ");
                }
            }
            for (int i = 0; i < atoms.length; i++) {
                synchronized (this) {
                    con.setChar(atoms[i]);
                    t2.notify();
                    try {
                        wait();
                    } catch (InterruptedException ex) {
                        JOptionPane.showMessageDialog(null, "Blad w wait()", "Blad!", JOptionPane.ERROR_MESSAGE);
                    }
                }
            }

        }
    }

    public class Consumer implements Runnable {

        char atom;

        public void setChar(char c) {
            atom = c;
        }

        @Override
        public void run() {
            while (true) {
                synchronized (this) {
                    try {
                        wait();
                    } catch (InterruptedException ex) {
                        JOptionPane.showMessageDialog(null, "Blad w wait()", "Blad!", JOptionPane.ERROR_MESSAGE);
                    }
                    System.out.println(atom);
                    t1.notify();
                }
            }
        }
    }

    public static void main(String[] args) {
        new Main();
    }
}

回答by radai

you need to be the "owner of the object's monitor" to be able to call notify on it. so far your methods are all synchronized(this), yet they call notify() on other objects (that they are not synchronized on). in other words:

您需要成为“对象监视器的所有者”才能对其调用通知。到目前为止,您的方法都是synchronized(this),但它们在其他对象上调用 notify() (它们未同步)。换句话说:

synchronized(t2) {
   t2.notify();
}

and

synchronized(t1) {
   t1.notify();
}

for a complete explanation of monitors and synchronization in java, see here, or look for similar questions here on SO, like this one - Java Wait and Notify: IllegalMonitorStateException

有关 Java 中监视器和同步的完整说明,请参见此处,或在此处查找类似的问题,例如 - Java Wait and Notify: IllegalMonitorStateException