(原創)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代碼塊即可。也奉勸,先把筆記看了之后再敲代碼,能為調試省不少時間。。。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM