【问题标题】:Using Explicit Lock to avoid deadlock gives an Exception使用显式锁来避免死锁会产生异常
【发布时间】:2012-02-10 15:42:50
【问题描述】:

我在这里尝试做的是有一个共享资源,即 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”, 第三行是“THREAD HECTOR [true]”,

然后程序退出。

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

线程 t2 在 setBFlag() 和 signal() 方法中获取锁,即通知其他线程它已释放锁,

t1 将再次获得锁,并且由于标志的变化,打破了 while 循环,在 finally 块中释放锁。

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

你能告诉我我在哪里失踪,

我哪里错了

【问题讨论】:

  • 为什么需要B-Flag?哪一行导致异常? -> 堆栈跟踪
  • 你应该按照try{之前获取锁的习语如果因为lock()而抛出异常,finally中的unlock也会抛出异常。

标签: java multithreading thread-safety


【解决方案1】:

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

他们做的事情非常不同。

【讨论】:

    【解决方案2】:

    当调用wait()/notify() 方法时,你应该持有内部对象锁。你打电话给condition.wait(),而不是condition.await()。这应该是您的IllegalMonitorState 异常的原因。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-31
      • 2017-12-17
      • 1970-01-01
      • 2020-10-25
      • 2012-10-30
      • 1970-01-01
      相关资源
      最近更新 更多