使用Explicit Lock来避免死锁会产生异常

时间:2012-02-10 15:42:50

标签: java multithreading thread-safety

我在这里要做的是有一个共享资源,即SharedResource777.java, 这个类有两个方法doIt()和setBFlag(),两个线程都获取Lock并使用线程执行方法。

代码如下,

    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”, 第三行是“THE THREAD HECTOR [true]”,

并退出程序。

我试图做的是Thread T1将执行doIt(),然后获取锁而不是进入while循环,打印SOP等待,这将释放Lock。

比线程t2获取方法setBFlag()和signal()中的锁,即notify()到已释放锁的其他线程,

t1将再次获取锁定,并且由于标志更改,打破while循环,释放finally块中的锁定。

但在我的情况下,我得到一个例外,

你能告诉我我失踪的地方吗,

我出错的地方

2 个答案:

答案 0 :(得分:6)

我认为您的condition.wait();应该是condition.await();

他们做了很多不同的事情。

答案 1 :(得分:0)

调用wait()/notify()方法时,应该保持内部对象锁定。您正在呼叫condition.wait()而不是condition.await()。这应该是IllegalMonitorState例外的原因。