Использование явной блокировки, чтобы избежать тупика, дает исключение - PullRequest
0 голосов
/ 10 февраля 2012

что я пытаюсь сделать здесь, это общий ресурс, то есть SharedResource777.java, этот класс имеет два метода doIt () и setBFlag (), оба потока получают блокировку и выполняют метод с использованием потока.

код, как показано ниже,

    import java.util.concurrent.locks.*;

    class SharedResource777{
        private boolean bFLag = false;
        private Lock lockObj = new ReentrantLock();
        private Condition condition = lockObj.newCondition();

        public void doIt() {        
            try{
                lockObj.lock();         
                while(!bFLag){
                    System.out.println(" THE THREAD "+Thread.currentThread().getName());            
                    condition.wait();
                }           
            }catch(Exception e){
                System.out.println(e);
            }finally{
                lockObj.unlock();
            }           
        }

        public void setBFlag(boolean bFLag){        
            try{
                lockObj.lock(); 
                this.bFLag = bFLag;     
                System.out.println(" THE THREAD "+Thread.currentThread().getName()+" ["+this.bFLag+"]");
                condition.signal();
            }catch(Exception e){
                System.out.println(e);
            }finally{
                lockObj.unlock();
            }
        }

    }

    class MyThread620 extends Thread{

        private SharedResource777 resource;

        MyThread620(String threadName,SharedResource777 resource){
            super(threadName);
            this.resource = resource;
        }

        @Override
        public  void run(){
            resource.doIt();            
        }
    }

    class MyThread621 extends Thread{

        private SharedResource777 resource;

        MyThread621(String threadName,SharedResource777 resource){
            super(threadName);
            this.resource = resource;
        }

        @Override
        public  void run(){
            resource.setBFlag(true);                    
        }
    }



    public class Ex11{
        public static void main(String [] args){
            SharedResource777 obj777 = new SharedResource777();
            MyThread620 t620 = new MyThread620("TROY",obj777);
            MyThread621 t621 = new MyThread621("HECTOR",obj777);
            t620.start();
            t621.start();
        }
    }

Что происходит здесь, в командной строке первая строка «THE THREAD TROY», вторая строка "java.lang.IllegalMonitorStateException", третья строка - "ГРЕТОР РЕЗЬБЫ [true]",

и программа завершается.

То, что я пытался сделать, это то, что поток T1 выполнит doIt (), который, в свою очередь, получит блокировку, а затем войдет в цикл while, напечатает ожидание SOP, которое снимет блокировку.

Чем поток t2 получает блокировку в методе setBFlag () и signal (), т.е. notify () другому потоку, который снял блокировку,

t1 снова получит блокировку и из-за смены флага прерывает цикл while, снимает блокировку в блоке finally.

Но в моем сценарии я получаю исключение,

Подскажите, пожалуйста, где мне не хватает,

Где я иду не так

Ответы [ 2 ]

6 голосов
/ 10 февраля 2012

Я думаю, что ваши condition.wait(); действительно должны быть condition.await();

Они делают очень разные вещи.

0 голосов
/ 10 февраля 2012

При вызове методов wait()/notify() вы должны удерживать встроенную блокировку объекта. Вы звоните condition.wait(), а не condition.await(). Это должно быть причиной вашего IllegalMonitorState исключения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...