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

关于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 如何用Labview在myRIO上做LCD显示?(语言-开发语言)
  • ¥15 Vue3地图和异步函数使用
  • ¥15 C++ yoloV5改写遇到的问题
  • ¥20 win11修改中文用户名路径
  • ¥15 win2012磁盘空间不足,c盘正常,d盘无法写入
  • ¥15 用土力学知识进行土坡稳定性分析与挡土墙设计
  • ¥70 PlayWright在Java上连接CDP关联本地Chrome启动失败,貌似是Windows端口转发问题
  • ¥15 帮我写一个c++工程
  • ¥30 Eclipse官网打不开,官网首页进不去,显示无法访问此页面,求解决方法
  • ¥15 关于smbclient 库的使用