当前位置: 首页 > 知识库问答 >
问题:

IllegalMonitorStateException notify()和wait()[duplicate]

罗渝
2023-03-14

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

我必须这样做,一个线程将发送到第二个线程char,然后这个线程必须等待和第二个线程打印这个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个答案

赏星河
2023-03-14

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

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

而且

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

有关Java中监视器和同步的完整解释,请参阅此处,或在SO上查找类似的问题,如以下内容--Java等待并通知:IllegalMonitorStateException

 类似资料:
  • 问题内容: 似乎该线程都在其他线程调用或在此线程上唤醒。两者之间有什么区别吗? - 编辑 - 我知道一个是通知对象,另一个是中断线程。但是,这两种情况都会导致相同的结果,也就是说,该线程被唤醒,所以我想问的是这两种情况的后果是如何不同的。 问题答案: 当线程在某个监视器上调用notify时,它将唤醒在该监视器上等待的单个线程,但是 哪个 线程被唤醒由调度程序决定。(或者,一个线程可以调用notif

  • 描述 (Description) 此函数等待子进程终止,返回已故进程的进程ID。 该流程的退出状态包含在$?中。 语法 (Syntax) 以下是此函数的简单语法 - wait 返回值 (Return Value) 如果没有子进程,则此函数返回-1,否则返回已故进程的进程ID<!-- 例子 (Example) Following is the example code showing its ba

  • wait(等待子进程中断或结束) 相关函数 waitpid,fork 表头文件 #include<sys/types.h> #include<sys/wait.h> 定义函数 pid_t wait (int * status); 函数说明 wait()会暂时停止目前进程的执行,直到有信号来到或子进程结束。如果在调用wait()时子进程已经结束,则wait()会立即返回子进程结束状态值。子进程的结束

  • wait 等待子进程中断或结束 相关函数 waitpid,fork 表头文件 #include<sys/types.h> #include<sys/wait.h> 定义函数 pid_t wait(int *status); 函数说明 wait()会暂时停止目前进程的执行,直到有信号来到或子进程结束。如果在调用wait()时子进程已经结束,则wait()会立即返回子进程结束状态值。子进程的结束状

  • 我试图做到这一点:创建两个不同的线程,一个打印奇数,一个打印偶数。一旦一个线程打印出一个数字,它就必须等待另一个线程,以此类推,这是一个接一个的。 为了实现这一点,我将使用synchronized block以及wait()和notify()。 我正在创建一个类,该类的对象将用于传递给两个线程中的同步块。 -- --- SyncObject作为参数传递给main中的这些不同线程。 但是,此程序会停

  • wait 用法 Usage: docker wait [OPTIONS] CONTAINER [CONTAINER...] Block until a container stops, then print its exit code. --help=false Print usage 说明 阻塞对指定容器的其他调用方法,直到容器停止后退出阻塞。