2009-11-19 3 views
2

Je souhaite utiliser ce type de flux de travail en utilisant des variables de verrouillage/condition explicites (c'est un projet de cours qui impose ce style): A est la classe principale, demande à B de faire un travail de temps en temps. B a une classe de travail C qui interroge constamment B sur les nouveaux travaux à faire et à faire. Une fois C terminé, il appelle la fonction de rappel de A pour notifier A que le travail est terminé.IllegalMonitorStateException levée avec verrouillage/condition explicite

Cependant, lorsque j'essaie d'exécuter le programme, j'obtiens une exception IllegalMonitorStateException, lorsque le callback() essaie de notifier la fonction doit().

exception in thread "Thread-0" java.lang.IllegalMonitorStateException 
     at java.lang.Object.notifyAll(Native Method) 
     at Test$A.callback(Test.java:49) 
     at Test$C.run(Test.java:115) 

Je regardais les javadoc et certains Q & A propos de cette exception, mais toujours aucune idée pourquoi je reçois cela.

import java.util.*; 
import java.util.concurrent.locks.ReentrantLock; 
import java.util.concurrent.locks.Condition; 

public class Test { 
    public class A 
    { 
     private ReentrantLock lock; 
     private Condition cond; 
     private boolean bool; 
     private B b; 
     public A() 
     { 
      this.lock = new ReentrantLock(); 
      this.cond = lock.newCondition(); 
      b = new B(this); 
      bool = false; 
     } 

     public void doit() 
     { 
      try { 
       lock.lock(); 
       b.letgo(); 
       while (!bool) { 
        System.out.println("A::doit() Block."); 
        cond.awaitUninterruptibly(); 
       } 
       System.out.println("A::doit() Done."); 
      } 
      finally { 
       lock.unlock(); 
      } 
     } 

     public void callback() { 
      try { 
       lock.lock(); 
       bool = true; 
       cond.notify(); 
       System.out.println("A::callback() done."); 
      } 
      finally { 
       lock.unlock(); 
      } 
     } 
    } 

    public class B 
    { 
     private C c; 
     private ReentrantLock lock; 
     private Condition cond; 
     private boolean bool; 
     public B(A a) 
     { 
      this.lock = new ReentrantLock(); 
      this.cond = lock.newCondition(); 
      bool = false; 
      c = new C(a, this); 
      c.start(); 
     } 

     public void letgo() 
     { 
      try { 
       lock.lock(); 
       bool = true; 
      } 
      finally { 
       lock.unlock(); 
      } 
     } 

     public void get() 
     { 
      try { 
       lock.lock(); 
       while (!bool) { 
        cond.awaitUninterruptibly(); 
       } 
       bool = false; 
       return; 
      } 
      finally { 
       lock.unlock(); 
      } 
     } 
    } 

    public class C extends Thread 
    { 
     private A a; 
     private B b; 

     public C(A a, B b) 
     { 
      this.a = a; 
      this.b = b; 
     } 

     public void run() 
     { 
      while (true) { 
       b.get(); 
       a.callback(); 
      } 
     } 
    } 

    public static void main(String args[]) 
    { 
     Test t = new Test(); 
     t.test1(); 
    } 

    public void test1() 
    { 
     A a = new A(); 
     a.doit(); 
    } 
} 
+0

Quelle ligne est 'at Test $ A.callback (Test.java:49)' –

Répondre

4

utiliser la méthode signal()Condition sur la place de notify().

Pendant que vous puissiez réussir synchronize sur une instance Condition, puis utilisez les wait() et notify() méthodes traditionnelles, vous pourriez tout aussi bien utiliser un Object si vous n'utilisez pas les capacités étendues des classes concurrentes.

Condition était destiné à être utilisé avec les méthodes équivalentes await() et signal(), et leurs variantes améliorées.

+0

Je viens de le trouver moi-même ... merci pour la réponse rapide! – CyberSnoopy