热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

ExceptioninthreadThread0java.lang.IllegalMonitorStateException

Exception in thread "Thread-0" java.lang.IllegalMonitorStateException线程“thread -0”java.lang.IllegalM

Exception in thread "Thread-0" java.lang.IllegalMonitorStateException

线程“thread -0”java.lang.IllegalMonitorStateException中的异常

 


/*** * Title:生产者* Description:* @author lcs* @date 2018年12月12日* @version 1.0*/
public class Productor implements Runnable{private static String[] goodsType={"iPhone7", "iPhone8", "iPhoneX", "博世冰箱", "格力空调", "吉利房车", "电动汽车", "思科路由器", "华为交换机", "大疆无人机"};private static final int STORE_MAX = 1000;//单例,getProductorprivate static Productor productor=null;public static Productor getProductor(){if(productor == null)productor =new Productor();//创建的时候就使用无参构造方法return productor;}//编写无参构造方法private Productor(){//要给出具体的实现方法,总是增删改,所以用linkedList方法store = new LinkedList();}//库存private List store;//再搞把锁对象private Object lock;public void setLock(Object lock){this.lock=lock;}//此方法为从库存中获取一个商品的最基本操作//此方法只会在消费者线程中调用,因此我们可以在消费者处进行同步//库存store也是private的,消费这个操作不好直接对库存进行操作 //是给Consumer配置的方法,增加是add往最后加,那么消费的时候就remove(0),从头拿//有一个就拿一个,疑问若有类型A的东西,但没有类型b的东西,但是拿b怎么办?public Goods getOneGoods(){Goods g =null;if (store.size()==0) return null;g=store.remove(0);//打印库存剩余产品数量System.out.println("消费一个商品,库存目前剩余:" + store.size());return g;}//一次生产N个产品,N设定为5-10//一批产品,为能够生产的10种中的同一种产品private void produceGoods(){//随机出本次商品的数量int n= (int) (Math.random()*101+50);//随机出商品的种类int type= (int) (Math.random()*10);String gType=goodsType[type];int i;synchronized (lock) {for ( i = 0; i //意思是不可能让一直生产,cpu主频很快,得休息一下啊Thread.sleep(1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}

出现这个问题是没有把判断条件放入到synchronized方法块里面

生产者和消费者两个都是多线程,不管别人怎么样,自己生产,同时也消费

synchronized(this) //锁住当前对象的引用,则任何线程通过当前线程访问到此句,会锁住,直到放开锁,其他线程才能进来。

重写run方法:run()称为线程体,它包含了要执行的这个线程的内容,Run方法运行结束,此线程终止,而CPU再运行其它线程

想想哪里可能有线程冲突:1,生产的时候add,另一个线程消费了remove了,底层不知道,尼玛你到底想干嘛,我操2,一个线程看到还有一个产品,两个线程同时去消费这个产品,产生空指针异常

所以呢,方法前面加synchronized,但是Productor是一个单例对象,这个对象拿来同步,但是Consumer怎么同步呢?

所以,把对生产者库存的这个数据要保护起来,把跟集合有关系的包进来

package com.chinasofti.ProductorConsumer;public class Goods {//当前一共产出了多少个货物public static int count = 0;//生产了产品,name就是public static Goods createOneGoods(String name){count++;return new Goods(count,name);}private Goods(int id, String name) {this.id = id;this.name = name;}private int id;//一个货物对象一个id编号private String name;@Overridepublic String toString() {return "Goods [id=" + id + ", name=" + name + "]";}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}}

 

package com.chinasofti.ProductorConsumer;public class Consumer extends Thread{private static int consumedGoods = 0;private Object lock;public Consumer(String name){super(name);}public void setLock(Object lock) {this.lock = lock;}private void consumeGoods(){//一次消费N个商品,从生产商处拿货int n = (int)(Math.random()*2 + 1);//一次消费10-20个商品synchronized (lock) {for(int i=0;i}

package com.chinasofti.ProductorConsumer;public class TestClass {public static void main(String[] args) {Object lock &#61;new Object();//生产者消费者都用一个锁Thread productor &#61;new Thread(Productor.getProductor());Productor.getProductor().setLock(lock);productor.start();try {Thread.sleep(2000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}//十个顾客for(int i&#61;0;i<10;i&#43;&#43;){Consumer consumer &#61;new Consumer("顾客"&#43;i&#43;1);consumer.setLock(lock);consumer.start();}}
}

 


推荐阅读
  • 在Docker中,将主机目录挂载到容器中作为volume使用时,常常会遇到文件权限问题。这是因为容器内外的UID不同所导致的。本文介绍了解决这个问题的方法,包括使用gosu和suexec工具以及在Dockerfile中配置volume的权限。通过这些方法,可以避免在使用Docker时出现无写权限的情况。 ... [详细]
  • 阿,里,云,物,联网,net,core,客户端,czgl,aliiotclient, ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
  • FeatureRequestIsyourfeaturerequestrelatedtoaproblem?Please ... [详细]
  • 本文讨论了如何使用IF函数从基于有限输入列表的有限输出列表中获取输出,并提出了是否有更快/更有效的执行代码的方法。作者希望了解是否有办法缩短代码,并从自我开发的角度来看是否有更好的方法。提供的代码可以按原样工作,但作者想知道是否有更好的方法来执行这样的任务。 ... [详细]
  • 本文详细介绍了如何使用MySQL来显示SQL语句的执行时间,并通过MySQL Query Profiler获取CPU和内存使用量以及系统锁和表锁的时间。同时介绍了效能分析的三种方法:瓶颈分析、工作负载分析和基于比率的分析。 ... [详细]
  • IjustinheritedsomewebpageswhichusesMooTools.IneverusedMooTools.NowIneedtoaddsomef ... [详细]
  • 开发笔记:计网局域网:NAT 是如何工作的?
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了计网-局域网:NAT是如何工作的?相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • JDK源码学习之HashTable(附带面试题)的学习笔记
    本文介绍了JDK源码学习之HashTable(附带面试题)的学习笔记,包括HashTable的定义、数据类型、与HashMap的关系和区别。文章提供了干货,并附带了其他相关主题的学习笔记。 ... [详细]
  • mac php错误日志配置方法及错误级别修改
    本文介绍了在mac环境下配置php错误日志的方法,包括修改php.ini文件和httpd.conf文件的操作步骤。同时还介绍了如何修改错误级别,以及相应的错误级别参考链接。 ... [详细]
  • RouterOS 5.16软路由安装图解教程
    本文介绍了如何安装RouterOS 5.16软路由系统,包括系统要求、安装步骤和登录方式。同时提供了详细的图解教程,方便读者进行操作。 ... [详细]
  • This article discusses the efficiency of using char str[] and char *str and whether there is any reason to prefer one over the other. It explains the difference between the two and provides an example to illustrate their usage. ... [详细]
author-avatar
一叶之秋
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有