9

私は問題があります。同期ブロックで使用するnotify()と、IllegalMonitorStateExceptionが発生します。誰かが私がこの問題を解決するのを手伝ってもらえますか?

2番目のスレッドにcharを送信するために1つのスレッドが必要です。その後、このスレッドは待機する必要があり、2番目のスレッドはこのcharを出力します。その2番目のスレッドが待機した後、最初のスレッドが再び次の文字を送信します

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

1 に答える 1

14

通知を呼び出すには、「オブジェクトのモニターの所有者」である必要があります。これまでのところ、メソッドはすべてsynchronized(this)ですが、他のオブジェクトでnotify()を呼び出します(同期されていません)。言い換えると:

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

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

Javaでのモニターと同期の完全な説明については、ここを参照するか、SOで同様の質問を探してください。たとえば、Java Wait and Notify:IllegalMonitorStateException

于 2013-01-09T11:58:55.220 に答える