IllegalMonitorStateException notify() и wait()

У меня проблема. Когда я использую notify() в синхронизированном блоке у меня есть IllegalMonitorStateException. Может кто-нибудь помочь мне решить эту проблему?

Я должен сделать это, один поток отправит второй символ char, затем этот поток должен ждать, а второй поток распечатать этот символ. После этого второй поток ожидания, и первый снова отправить следующий символ

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 ответ

Решение

Вы должны быть "владельцем монитора объекта", чтобы иметь возможность вызывать уведомление об этом. пока ваши методы все synchronized(this), но они вызывают notify() для других объектов (для которых они не синхронизированы). другими словами:

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

а также

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

для полного объяснения мониторов и синхронизации в Java смотрите здесь, или ищите подобные вопросы здесь на SO, как этот - Java Wait and Notify: IllegalMonitorStateException

Другие вопросы по тегам