Java 非法监视器状态异常

标签 java multithreading

我需要一些帮助来了解我的程序出了问题,我有一个非常简单的程序来学习多线程,但每次我运行以下代码时,它都会给我一个 IllegalStateMonitorException。我不知道是什么原因造成的,尽管我怀疑这可能是我的同步块(synchronized block),谢谢。

主要方法类:

public class Lab8 {
    public static void main(String [] args) { 
        Thread1 thread1 = new Thread1(); 
        thread1.start();
    }
}

主题 1:

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Thread1 extends Thread {
public DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");

public Thread1() { 
    super("Thread1");
}
public void run() { 
    Thread2 thread2 = new Thread2(); 
    System.out.println("==Start: " + dateFormat.format(new Date()) + "==\n"); 
    synchronized(thread2) { 
        try {
            this.wait();
        } catch (InterruptedException e) {
            System.err.println(e.toString()); 
        } 
        (new Thread(thread2)).start(); 
    }
    System.out.println("==End: " + dateFormat.format(new Date()) + "==\n"); 
}
}

主题 2:

public class Thread2 implements Runnable {
@Override
public void run() {
    synchronized(this) { 
        for(int i = 1; i <= 100; i++) { 
            System.out.print(i + " ");
            if(i % 10 == 0) { 
                System.out.print("\n");
            }
        }
        notify(); 
    }
} 

}

最佳答案

您应该明白,synchronized 构造和 wait/notify 机制与对象实例相关联。在您的代码中,您正在使用

synchronized(thread2) { 
   …
        this.wait();

因此,您的 synchronized 语句的对象和您正在调用 wait 的对象是不同的。这会导致 IllegalStateMonitorException。请注意,当另一个线程在其自己的 Thread2 实例上调用 notify() 时,等待 Thread1 实例将不会像 notify 那样工作 将仅唤醒在同一实例上等待的线程。

除此之外,无论如何你都不应该在线程实例上进行同步。原因是 Thread 实现也将在其自己的实例上同步,因此这可能会产生干扰。此外,您不应该像对 Thread1 类那样子类化 Thread ,而应该像对 Thread2 类那样使用组合。

关于Java 非法监视器状态异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31325064/

相关文章:

java - 获取所有记录,包括特定字段

java - 动态注入(inject)spring bean

ios - Xcode - 如何使用线程绘制 View ?

c - Linux,C : threads synch

java - 从构造函数调用虚方法

c# - 软件开发人员不将授权外部化是否有原因?

java - java中过滤器中的服务方法由谁来进行滚动?

multithreading - Clang 线程安全注解和共享功能

android - 处理 Activity 和 Thread 之间关系的常见做法是什么

c# - 在哪些线程上调用 SocketAsyncEventArgs Completed 以及在何处处理消息