,原创Java多线程作业题报java.lang.IllegalMonitorStateException解决

作业:

  有一个水池,水池容量500L,一边为进水口,一边为出水口,要求进水放水不能同时进行,水池一旦满了不能继续注水,一旦空了,不能继续放水,进水速度5L/s,放水速度2L/s。

  这是我学多线程时做的一道练习题,刚开始对wait()方法存在错误理解导致运行时报异常-----java.lang.IllegalMonitorStateException,修复后,在此把错误写法以及最终正确写法都整理出来。

class Water{

staticintlitre = 500;

boolean flag=true; //false为可以继续加水,true为可以继续放水

}

class OutPour extends Thread{ //出水类

Water w;

OutPour(Water w){

this.w=w;

}

@Override

publicvoid 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

publicvoid 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();

}

}

}

}

*/

}

publicclass Demo11 {

publicstaticvoid 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代码块即可。也奉劝,先把笔记看了之后再敲代码,能为调试省不少时间。。。