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

Java IllegalMonitorStateException[副本]

何玉韵
2023-03-14

我需要一些帮助来理解我的程序哪里出错了,我有一个非常简单的程序来学习多线程,但是每次我运行下面的代码时,它给我一个IllegalStateMonitorException。我不知道是什么原因造成的,虽然我怀疑它可能是我的同步块,谢谢。

主要方法类:

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

}

共有1个答案

宓毅庵
2023-03-14

您应该理解,synchronized构造和wait/notify机制是绑定到对象实例的。在您的代码中,您正在使用

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

因此,synchronized语句的对象和调用wait的对象是不同的。这会导致IllegalStateMonitorException。请注意,当其他线程在自己的Thread2实例上调用Notify()时,等待Thread1实例将无法工作,因为Notify将只唤醒等待同一实例的线程。

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

 类似资料:
  • 正如我所想的那样,我一直在解决一个算法问题并找到了解决方案。但没想到我遇到了一个奇怪的问题。 让我们假设我在英特尔第11代处理器java 8/17上有以下代码(两者都有): 把你的眼睛指向解决函数。 在这里我们有一个简单的解决方案,调用函数 n 次并测量所需的时间(我不使用 JMH,因为我的问题的测试系统使用简单的一次性时间测量)。在捕获开始时间之前,它使用内置的 函数按自然顺序对数组进行排序。

  • 我对这个(可能是)简单的铸造示例有一个棘手的问题。你能帮帮我吗? 但更尴尬的是,我不知道为什么其他两种说法都没问题。 我看不出OtherIf和ChildIf之间有任何联系。那么,在案例1中,当这两个接口之间没有“扩展”时,如何将OtherIf强制转换为ChildIf呢?

  • 问题内容: 我实现了此处描述的副本构造函数。但是问题仍然是,当我更新时,会将相同的更新应用于。所以,我不明白我的代码有什么问题? 问题答案: 在复制构造函数中,您只是在进行浅表复制,而您需要进行深表复制: 在这里,您仍在复制的引用,该引用仍指向same 。您也应该对其进行修改以创建列表的副本。可能还需要像下面这样在arraylist中创建元素的副本:

  • 我不懂pyplot。子地块(330 1 i)

  • 只读操作: 有没有办法有一个MongoDB副本集,但要使连接到的框上的MongoDB实例成为被查询的MongoDB? 我在AWS负载平衡器后面有三个EC2实例。 在每个EC2实例上运行MongoDB,它是副本集的一部分。 我在nodeJS上有expressendpoint,我连接到副本集,如下所示 我希望在MongoDB副本集的所有三个实例上均匀分布查询负载,而不是默认情况下将所有查询路由到定义了

  • 简单的赋值不会创建数组对象的副本。 相反,它使用原始数组的相同来访问它。 id()返回 Python 对象的通用标识符,类似于 C 中的指针。 此外,一个数组的任何变化都反映在另一个数组上。 例如,一个数组的形状改变也会改变另一个数组的形状。 我们的数组是: [0 1 2 3 4 5] 调用 id() 函数: 139747815479536 a 赋值给 b: [0 1 2 3 4 5] b 拥有相