热门标签 | 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();}}
}

 


推荐阅读
  • 深入解析Redis内存对象模型
    本文详细介绍了Redis内存对象模型的关键知识点,包括内存统计、内存分配、数据存储细节及优化策略。通过实际案例和专业分析,帮助读者全面理解Redis内存管理机制。 ... [详细]
  • Nginx 反向代理与负载均衡实验
    本实验旨在通过配置 Nginx 实现反向代理和负载均衡,确保从北京本地代理服务器访问上海的 Web 服务器时,能够依次显示红、黄、绿三种颜色页面以验证负载均衡效果。 ... [详细]
  • 本文探讨了如何通过预处理器开关选择不同的类实现,并解决在特定情况下遇到的链接器错误。 ... [详细]
  • 深入解析Spring启动过程
    本文详细介绍了Spring框架的启动流程,帮助开发者理解其内部机制。通过具体示例和代码片段,解释了Bean定义、工厂类、读取器以及条件评估等关键概念,使读者能够更全面地掌握Spring的初始化过程。 ... [详细]
  • 本文详细介绍了 org.apache.commons.io.IOCase 类中的 checkCompareTo() 方法,通过多个代码示例展示其在不同场景下的使用方法。 ... [详细]
  • 对象自省自省在计算机编程领域里,是指在运行时判断一个对象的类型和能力。dir能够返回一个列表,列举了一个对象所拥有的属性和方法。my_list[ ... [详细]
  • 反向投影技术主要用于在大型输入图像中定位特定的小型模板图像。通过直方图对比,它能够识别出最匹配的区域或点,从而确定模板图像在输入图像中的位置。 ... [详细]
  • 在创建新的Android项目时,您可能会遇到aapt错误,提示无法打开libstdc++.so.6共享对象文件。本文将探讨该问题的原因及解决方案。 ... [详细]
  • 本文介绍了一个SQL Server自定义函数,用于从字符串中提取仅包含数字和小数点的子串。该函数通过循环删除非数字字符来实现,并附带创建测试表、存储过程以演示其应用。 ... [详细]
  • 本文详细解析了Java中hashCode()和equals()方法的实现原理及其在哈希表结构中的应用,探讨了两者之间的关系及其实现时需要注意的问题。 ... [详细]
  • 采用IKE方式建立IPsec安全隧道
    一、【组网和实验环境】按如上的接口ip先作配置,再作ipsec的相关配置,配置文本见文章最后本文实验采用的交换机是H3C模拟器,下载地址如 ... [详细]
  • 本文介绍了如何在多线程环境中实现异步任务的事务控制,确保任务执行的一致性和可靠性。通过使用计数器和异常标记字段,系统能够准确判断所有异步线程的执行结果,并根据结果决定是否回滚或提交事务。 ... [详细]
  • NTP服务器配置详解:原理与工作模式
    本文深入探讨了网络时间协议(NTP)的工作原理及其多种工作模式,旨在帮助读者全面理解NTP的配置参数和应用场景。NTP是基于RFC 1305的时间同步标准,广泛应用于分布式系统中,确保设备间时钟的一致性。 ... [详细]
  • 在高并发需求的C++项目中,我们最初选择了JsonCpp进行JSON解析和序列化。然而,在处理大数据量时,JsonCpp频繁抛出异常,尤其是在多线程环境下问题更为突出。通过分析发现,旧版本的JsonCpp存在多线程安全性和性能瓶颈。经过评估,我们最终选择了RapidJSON作为替代方案,并实现了显著的性能提升。 ... [详细]
  • 在尝试使用C# Windows Forms客户端通过SignalR连接到ASP.NET服务器时,遇到了内部服务器错误(500)。本文将详细探讨问题的原因及解决方案。 ... [详细]
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社区 版权所有