(原创)Java多线程作业题报java.lang.IllegalMonitorStateException解决
作业:
有一个水池,水池容量500L,一边为进水口,一边为出水口,要求进水放水不能同时进行,水池一旦满了不能继续注水,一旦空了,不能继续放水,进水速度5L/s,放水速度2L/s。
这是我学多线程时做的一道练习题,刚开始对wait()方法存在错误理解导致运行时报异常-----java.lang.IllegalMonitorStateException,修复后,在此把错误写法以及最终正确写法都整理出来。
class Water{
static int litre = 500;
boolean flag=true; //false为可以继续加水,true为可以继续放水
}
class OutPour extends Thread{ //出水类
Water w;
OutPour(Water w){
this.w=w;
}
@Override
public void run() { //正确写法
while(true){
synchronized(w){
if(w.flag==true){ //放水,2L/s
try {
Thread.sleep(60);
} catch (InterruptedException e) {
e.printStackTrace();
}
w.litre=w.litre-2;
System.out.println("放水中,现在还剩"+w.litre+"升水!");
if(w.litre<=0){ //放空了
w.flag=false;
System.out.println("--------空了!--------");
w.notify();
}
}else{
try {
w.wait();//等加满
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
/*
@Override
public void run() { //错误写法
while(true){
if(w.flag==true){ //放水,2L/s
synchronized(w){
try {
Thread.sleep(60);
} catch (InterruptedException e) {
e.printStackTrace();
}
w.litre=w.litre-2;
System.out.println("放水中,现在还剩"+w.litre+"升水!");
if(w.litre<=0){ //放空了
w.flag=false;
System.out.println("--------空了!--------");
w.notify
}
}
}else{
try {
w.wait();//等加满
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
*/
}
class InPour extends Thread{ //进水类
Water w;
InPour(Water w){
this.w=w;
}
@Override
public void run() { //正确写法
while(true){
synchronized(w){
if(w.flag==false){//加水,5L/s
try {
Thread.sleep(60);
} catch (InterruptedException e) {
e.printStackTrace();
}
w.litre=w.litre+5;
System.out.println("加水中,现在有"+w.litre+"升水!");
if(w.litre>=500){//加满了
System.out.println("-------满了!-------");
w.flag=true;
w.notify();
}
}else{
try {
w.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
/*
@Override
public void run() { //错误写法
while(true){
if(w.flag==false){ //加水,5L/s
synchronized(w){
try {
Thread.sleep(60);
} catch (InterruptedException e) {
e.printStackTrace();
}
w.litre=w.litre+5;
if(w.litre>=500){ //加满了
System.out.println("-------满了!-------");
w.flag=true;
w.notifyAll();
}
}
}else{
try {
w.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
*/
}
public class Demo11 {
public static void main(String[] args){
Water w = new Water();
OutPour o = new OutPour(w);
InPour i = new InPour(w);
o.start();
i.start();
}
}
run方法在业务逻辑上并没有错,报异常java.lang.IllegalMonitorStateException,是因为wait()方法必须要放在同步代码块中才能使用。把else{}语句也圈到synchronized代码块即可。也奉劝,先把笔记看了之后再敲代码,能为调试省不少时间。。。
(原创)Java多线程作业题报java.lang.IllegalMonitorStateException解决的更多相关文章
- Java多线程编程核心技术---Java多线程技能
基本概念 进程是操作系统结构的基础,是一次程序的执行,是一个程序及其数据结构在处理机上顺序执行时所发生的活动,是程序在一个数据集合上运行的过程,是系统进行资源分配和调度的独立单位.线程可以理解成是在进 ...
- 解决:IDEA unable to import maven project see logs for details问题+java http请求报java.net.SocketException: Permission denied:connect 问题
背景:用IDEA写了一个java发送http请求的maven项目. 运行时,项目报java.net.SocketException: Permission denied:connect问题: 修改po ...
- (1)Java多线程编程核心——Java多线程技能
1.为什么要使用多线程?多线程的优点? 提高CPU的利用率 2.什么是多线程? 3.Java实现多线程编程的两种方式? a.继承Thread类 public class MyThread01 exte ...
- Java多线程编程(1)--Java中的线程
一.程序.进程和线程 程序是一组指令的有序集合,也可以将其通俗地理解为若干行代码.它本身没有任何运行的含义,它只是一个静态的实体,它可能只是一个单纯的文本文件,也有可能是经过编译之后生成的可执行文 ...
- 【java多线程系列】java内存模型与指令重排序
在多线程编程中,需要处理两个最核心的问题,线程之间如何通信及线程之间如何同步,线程之间通信指的是线程之间通过何种机制交换信息,同步指的是如何控制不同线程之间操作发生的相对顺序.很多读者可能会说这还不简 ...
- java 多线程5: java 终止线程及中断机制 (stop()、interrupt() 、interrupted()、isInterrupted())
JAVA中有3种方式可以终止正在运行的线程 ①线程正常退出,即run()方法执行完毕了 ②使用Thread类中的stop()方法强行终止线程.但stop()方法已经过期了,不推荐使用 ③使用中断机制i ...
- java多线程基础(二)--java多线程的基本使用
java多线程的基本使用 在java中使用多线程,是通过继承Thread这个类或者实现Runnable这个接口或者实现Callable接口来完成多线程的. 下面是很简单的例子代码: package c ...
- Java多线程系列一——Java实现线程方法
Java实现线程的两种方法 继承Thread类 实现Runnable接口 它们之间的区别如下: 1)Java的类为单继承,但可以实现多个接口,因此Runnable可能在某些场景比Thread更适用2) ...
- grade配置添加java库导致报 java.lang.RuntimeException: java.lang.RuntimeException: com.android.builder.dexing.DexArchiveMerger
原因是导入的第三方库中也引入了项目中存在的相同名称的库,导致产生冲突
随机推荐
- Apache2 MPM 模式了解
一.MPM MPM(Multi-Processing Module (MPM) implements a hybrid multi-process multi-threaded server)是Apa ...
- python------unicode字符串转换为其他类型
问题描述: 一下字符串转换为json类型 {u'src': u'crawl', u'cid': u'Ctengbangguoji', u'datatype': u'ItemBase', u'times ...
- Mysql中Insert into xxx on duplicate key update问题
要点:Insert into xxx on duplicate key update可以在唯一索引重复的情况下,进行更新操作. (1) 插入里边的字段应该只有一个 唯一索引: ...
- STM32音乐播放器,文件查找的实现
使用FATFS只是完成了一个基本的文件读写,有时候我们需要扩展一些功能,比如MP3实验,需要上一曲下一曲的切换,扩展的代码如下 //显示目录下所有文件 u8 ShowFileList(u8* dirP ...
- BZOJ 2209: [Jsoi2011]括号序列 [splay 括号]
2209: [Jsoi2011]括号序列 Time Limit: 20 Sec Memory Limit: 259 MBSubmit: 1111 Solved: 541[Submit][Statu ...
- Android线程之Thread 、Runnable 的两个例子
Thread例子: package fy.test; import android.app.Activity; import android.os.Bundle; import android.os. ...
- iOS开发 调用系统相机和相册 分类: ios技术 2015-03-30 15:52 65人阅读 评论(0) 收藏
调用系统相机和相册 (iPad,iPhone) 打开相机:(iPad,iPhone) //先设定sourceType为相机,然后判断相机是否可用(ipod)没相机,不可用将sourceType设定为 ...
- 基于RBAC的权限设计模型
个部件模型组成,这4个部件模型分别是基本模型RBAC0(Core RBAC).角色分级模型RBAC1(Hierarchal RBAC).角色限制模型RBAC2(Constraint RBAC)和统一模 ...
- zMPLS的安装与配置
1.zmpls的安装 1.1安装环境 ubuntu 12.04 kernel 2.6.35 (对原来的内核进行了替换) 1.2 下载链接 文件zMPLS-0.95-alpha.tar.gz的下载地址为 ...
- Java语言中IO流的操作规律学习笔记
1,明确源和目的. 数据源:就是需要读取,可以使用两个体系:InputStream.Reader: 数据汇:就是需要写入,可以使用两个体系:OutputStream.Writer: 总结: 读:就是把 ...