作业:

  有一个水池,水池容量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解决的更多相关文章

  1. Java多线程编程核心技术---Java多线程技能

    基本概念 进程是操作系统结构的基础,是一次程序的执行,是一个程序及其数据结构在处理机上顺序执行时所发生的活动,是程序在一个数据集合上运行的过程,是系统进行资源分配和调度的独立单位.线程可以理解成是在进 ...

  2. 解决: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 ...

  3. (1)Java多线程编程核心——Java多线程技能

    1.为什么要使用多线程?多线程的优点? 提高CPU的利用率 2.什么是多线程? 3.Java实现多线程编程的两种方式? a.继承Thread类 public class MyThread01 exte ...

  4. Java多线程编程(1)--Java中的线程

    一.程序.进程和线程   程序是一组指令的有序集合,也可以将其通俗地理解为若干行代码.它本身没有任何运行的含义,它只是一个静态的实体,它可能只是一个单纯的文本文件,也有可能是经过编译之后生成的可执行文 ...

  5. 【java多线程系列】java内存模型与指令重排序

    在多线程编程中,需要处理两个最核心的问题,线程之间如何通信及线程之间如何同步,线程之间通信指的是线程之间通过何种机制交换信息,同步指的是如何控制不同线程之间操作发生的相对顺序.很多读者可能会说这还不简 ...

  6. java 多线程5: java 终止线程及中断机制 (stop()、interrupt() 、interrupted()、isInterrupted())

    JAVA中有3种方式可以终止正在运行的线程 ①线程正常退出,即run()方法执行完毕了 ②使用Thread类中的stop()方法强行终止线程.但stop()方法已经过期了,不推荐使用 ③使用中断机制i ...

  7. java多线程基础(二)--java多线程的基本使用

    java多线程的基本使用 在java中使用多线程,是通过继承Thread这个类或者实现Runnable这个接口或者实现Callable接口来完成多线程的. 下面是很简单的例子代码: package c ...

  8. Java多线程系列一——Java实现线程方法

    Java实现线程的两种方法 继承Thread类 实现Runnable接口 它们之间的区别如下: 1)Java的类为单继承,但可以实现多个接口,因此Runnable可能在某些场景比Thread更适用2) ...

  9. grade配置添加java库导致报 java.lang.RuntimeException: java.lang.RuntimeException: com.android.builder.dexing.DexArchiveMerger

    原因是导入的第三方库中也引入了项目中存在的相同名称的库,导致产生冲突

随机推荐

  1. 使用for循环输出杨辉三角-还是不懂得需要复习

    package com.chongrui.test; /* *使用for循环输出杨辉三角杨辉三角形由数字排列,可以把它看作一个数字表,其基本特征是两侧的数值均为1,其他位置的数值是其正上方的数值与左上 ...

  2. iOS 主动抛出异常

    http://blog.csdn.net/jymn_chen/article/details/38096749 http://blog.sina.com.cn/s/blog_7270a06c0101b ...

  3. Maven的安装环境配置

    一.Maven的安装 二.Maven的配置 Settings.xml可以用来定义本地仓库.远程仓库.联网代理 Settings.xml文件可以存在两个地方: 1.多用户情况 conf目录下 2.单用户 ...

  4. 写一个程序,统计自己C语言共写了多少行代码。ver2.00

    概要 完成一个程序,作用是统计一个文件夹下面所有文件的代码行数.输入是一个文件夹的绝对路径,输出是代码行数.所以此程序的新特点有两个: 统计某一文件夹下的所有文件: 可以任意指定本机硬盘上任何位置的某 ...

  5. IOS开发-OC学习-protocol(协议)

    在OC语言中,协议是一组方法,里面有两种方法,一种是遵守这个协议的类的实例必须实现的方法,另一种是可以实现也可以不实现的方法. 例如我定义一个学生的协议,这个协议里有两个方法,其中一个是必选的方法:学 ...

  6. java基础(一)面向对象

    对象就是事物存在的实体,例如:人类,计算机等:而对象被分为两个部分,既动态与静态 类:就是同一事物的统称,如果将世界中的一个事物抽象成对象,类就是这类对象的统称,具有相同特性和行为的一类事物就是类. ...

  7. sql语句:CASE WHEN END 的用法

    select b,c, CASE a ' ' ' end from test1

  8. 轻轻的扩展了一下IEnumerable<T>

    今天用EF写东西玩,觉得IEnumerable里面除了where().select(),是不是能添加点其他方法呢. 想做就做,F12到方法定义: public static IEnumerable&l ...

  9. iOS 界面 之 EALayout 无需反复编译,可视化实时界面,告别Storyboard AutoLayout Xib等等烦人的工具

    http://blog.csdn.net/fatherhui iOS开发,EALayout 无需反复编译,可视化实时界面,告别Storyboard AutoLayout Xib等等烦人的工具 EALa ...

  10. jQuery对象插件封装步骤

    jQuery是js的一个非常优秀的库,它大大简化了js的很多操作,并且解决了js的大部分兼容性问题.甚至很多css兼容性问题,用jQuery写都能解决. 这里是对象插件的封装.当然,封装插件很多,这里 ...