朵朵粑 2018-06-10 09:38 采纳率: 100%
浏览 604
已采纳

关于Java多线程的问题,求大神解决

一个简单的例子,一个线程类代表客户,一个线程类代表厨师,
厨师每做好5个包子两个客户就吃,吃完再做。
运行时出现
java.lang.IllegalMonitorStateException错误,而且每次都只是一个人在吃。
实在是弄不明白了。。。
代码如下:
public class Resource {
//锁对象,静态资源,可以被公开访问
static Object lock = new Object();

//包子容器,静态资源,可以被公开访问
static List<String> container = new ArrayList<String>();

}

public class Producer implements Runnable {
@Override
public void run() {
// TODO Auto-generated method stub
while (true) {
synchronized ("") {
if (Resource.container.size() == 5) {
Resource.lock.notifyAll();// 唤醒所有在等待Resource.lock这把锁的线程
} else {
System.out.println("开始制作包子");
// 模拟耗时
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
Resource.container.add("包子");
}
}
}
}
}

public class Cutstom implements Runnable {
@Override
public void run() {
// TODO Auto-generated method stub

    while (true) {
        synchronized ("") {
            // 容器中没有包子了,吃货们就要等待包子
            if (Resource.container.size() == 0) {
                System.out.println("包子吃光啦,老板上包子");
                try {
                    Resource.lock.wait();// 释放自己持有了锁,并开始等待被notify
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            } else {
                // 模拟耗时
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                // 移除吃过的包子
                System.out.println("吃货:" + Thread.currentThread().getName() + "吃包子");
                Resource.container.remove(0);
            }
        }
    }
}

}

public class Test {

public static void main(String[] args) {
    // TODO Auto-generated method stub
    Cutstom cutstom = new Cutstom() ;
    new Thread(cutstom,"a").start() ;
    new Thread(cutstom,"b").start() ;
    Producer producer = new Producer() ;
    new Thread(producer,"c").start();
}

}

console:

Exception in thread "a" 包子吃光啦,老板上包子
java.lang.IllegalMonitorStateException
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Unknown Source)
at food.Cutstom.run(Cutstom.java:15)
at java.lang.Thread.run(Unknown Source)
开始制作包子
开始制作包子
开始制作包子
开始制作包子
开始制作包子
Exception in thread "c" java.lang.IllegalMonitorStateException
at java.lang.Object.notifyAll(Native Method)
at food.Producer.run(Producer.java:10)
at java.lang.Thread.run(Unknown Source)
吃货:b吃包子
吃货:b吃包子
吃货:b吃包子
吃货:b吃包子
吃货:b吃包子
包子吃光啦,老板上包子
Exception in thread "b" java.lang.IllegalMonitorStateException
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Unknown Source)
at food.Cutstom.run(Cutstom.java:15)
at java.lang.Thread.run(Unknown Source)

  • 写回答

2条回答 默认 最新

  • 强化脑细胞 2018-06-10 11:38
    关注

    首先你要了解这个异常为什么会抛出,这个异常会在三种情况下抛出:
    1>当前线程不含有当前对象的锁资源的时候,调用obj.wait()方法;
    2>当前线程不含有当前对象的锁资源的时候,调用obj.notify()方法。
    3>当前线程不含有当前对象的锁资源的时候,调用obj.notifyAll()方法。
    将Producer类中此位置由synchronized (“”) 改成synchronized (Resource.lock),将Cutstom类中此位置由synchronized (“”) 改成synchronized (Resource.lock) 问题解决。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 metadata提取的PDF元数据,如何转换为一个Excel
  • ¥15 关于arduino编程toCharArray()函数的使用
  • ¥100 vc++混合CEF采用CLR方式编译报错
  • ¥15 coze 的插件输入飞书多维表格 app_token 后一直显示错误,如何解决?
  • ¥15 vite+vue3+plyr播放本地public文件夹下视频无法加载
  • ¥15 c#逐行读取txt文本,但是每一行里面数据之间空格数量不同
  • ¥50 如何openEuler 22.03上安装配置drbd
  • ¥20 ING91680C BLE5.3 芯片怎么实现串口收发数据
  • ¥15 无线连接树莓派,无法执行update,如何解决?(相关搜索:软件下载)
  • ¥15 Windows11, backspace, enter, space键失灵