IllegalMonitorStateException notify()和wait()

10

我有一个问题。当我在同步块中使用notify()时,会出现IllegalMonitorStateException异常。有人能帮我解决这个问题吗?

我需要一个线程向第二个线程发送一个字符,然后这个线程必须等待,直到第二个线程打印这个字符。之后第二个线程等待,第一个线程再次发送下一个字符。

Main.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();
    }
}

1
请问您能够包含实际的异常内容吗? - radai
线程“Thread-2”中的异常java.lang.IllegalMonitorStateException 在java.lang.Object.notify(Native Method)处 在Main$Producent.run(Main.java:53)处 在java.lang.Thread.run(Thread.java:662)处 - Sylwek
可能是重复的 https://dev59.com/CnNA5IYBdhLWcg3wn_fD - Davut Gürbüz
1个回答

15

在调用 notify 方法时,需要成为“对象监视器的所有者”。你目前的方法都是 synchronized(this),但它们在其他对象上调用了 notify()(而这些对象没有被同步)。换句话说:

你需要成为一个对象的所有者才能在其上使用 notify 方法。目前,你的方法都使用了 synchronized(this),但是却在其他对象上调用了 notify 方法(这些对象并没有被同步)。换言之:

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

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

有关Java中监视器和同步的完整解释,请参见此处,或在SO上查找类似的问题,例如这个


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接