2017-03-19 1 views
2

Ich versuche, in die Konsole zu drucken, wenn die Methoden wait, notify und notifyAll in der Object-Klasse aufgerufen und zurückgegeben werden. Um dies zu erreichen, habe ich eine Wrapper-Klasse erstellt, die im Namen des Sperrobjekts die Methoden wait, notify und notifyAll aufruft. Ich benutze dann die Methoden auf dem Wrapper anstelle von warten, benachrichtigen und notifyAll. Hier ist mein bester Versuch dazu,Suche nach einer besseren Methode zur Protokollierung der Methoden wait() und notify()

Thema One läuft Runnable r1

Runnable r1 = new Runnable() { 
    @Override 
    public void run() { 
     synchronized (lock) { 
      try { 
       // wait not wrapped in while loop for brevity. 
       //lock.wait(); 
       lock.objWrapper.waitNew(); // Use the wrapper method instead of wait() 
      } catch (InterruptedException e) {} 
     } 
    } 
}; 

Thema Zwei Läufe Runnable r2

Runnable r2 = new Runnable() { 
    @Override 
    public void run() { 
     synchronized(lock) { 
      //lock.notifyAll(); 
      lock.objWrapper.notifyAllNew(); // Use the wrapper method instead of notifyAll() 
     } 
    } 
}; 

Die Klasse Sperre ist definiert als,

public class Lock { 
    ObjWrapper objWrapper = new ObjWrapper(this); 
    // shared data here 
} 

Lock lock = new Lock(); 

Die Wrapper-Klasse ist definiert als

public class ObjWrapper { 
    Object obj = null; 

    ObjWrapper(Object obj) { 
     System.out.println("New Object wrapper created: Thread: " + Thread.currentThread() + " at time: " + Instant.now()); 
     this.obj = obj; 
    } 

    public void waitNew() throws InterruptedException { 
     System.out.println("Entering Object::wait: Thread: " + Thread.currentThread() + " at time: " + Instant.now()); 
     obj.wait(); 
     System.out.println("Exiting Object::wait: Thread: " + Thread.currentThread() + " at time: " + Instant.now()); 
    } 

    public void notifyNew() { 
     System.out.println("Entering Object::notify: Thread: " + Thread.currentThread() + " at time: " + Instant.now()); 
     obj.notify(); 
     System.out.println("Exiting Object::notify: Thread: " + Thread.currentThread() + " at time: " + Instant.now()); 
    } 

    public void notifyAllNew() { 
     System.out.println("Entering Object::notifyAll: Thread: " + Thread.currentThread() + " at time: " + Instant.now()); 
     obj.notifyAll(); 
     System.out.println("Exiting Object::notifyAll: Thread: " + Thread.currentThread() + " at time: " + Instant.now()); 
    } 
} 

Und schließlich beginnen die Fäden verwenden,

Thread t1 = new Thread(r1); 
    t1.setName("Thread One"); 
    t1.start(); 

    Thread t2 = new Thread(r2); 
    t2.setName("Thread Two"); 
    t2.start(); 

Die Ausgabe auf Konsole,

New Object wrapper created: Thread: Thread[main,5,main] at time: 2017-03-19T22:48:28.771Z 
Entering Object::wait: Thread: Thread[Thread One,5,main] at time: 2017-03-19T22:48:28.844Z 
Entering Object::notifyAll: Thread: Thread[Thread Two,5,main] at time: 2017-03-19T22:48:31.845Z 
Exiting Object::notifyAll: Thread: Thread[Thread Two,5,main] at time: 2017-03-19T22:48:31.845Z 
Exiting Object::wait: Thread: Thread[Thread One,5,main] at time: 2017-03-19T22:48:31.845Z 

Meine Fragen sind,

  1. Gibt es eine andere bessere Weise zu tun Dies?
  2. Gibt es Randfälle, die bei der Verwendung des ObjWrapper kaputtgehen?

Bearbeiten: Ich bin nicht auf der Suche nach besseren Möglichkeiten, Objekte zu sperren. Einfach bessere Möglichkeiten, die Aufrufe von wait(), notify() und notifyAll() Methoden speziell zu protokollieren.

Antwort

0

Zu Frage 1, würde ich eher eine Unterklasse ReentrantLock und Condition, dann überschreiben das Signal und Methoden erwarten, da bei diesem Ansatz, Sie trotzdem die Möglichkeit verlieren das Stichwort auf Methode synchronisiert zu verwenden.

In Bezug auf Frage 2, der wichtigste Rand Fall hier, den ich hier sehen kann, ist, dass Sie durch intrinsic lock und Intrinsic-Condition-Warteschlange gebunden sind. Ein großer Vorbehalt ist meiner Meinung nach, dass Sie, wenn Sie ReentrantLock und/oder Condition verwenden möchten, neue Wrapper schreiben müssen (was vielleicht nicht einfach ist), was zu mehr Komplexität und mehr Problemen führt.

Nun, wie Sie wahrscheinlich bereits wissen, würde ich eher vorschlagen, auf höheren Ebenen APIs, dh Latches, Semaphors, Barriers, ConcurrentCollection, und so weiter zu bleiben und so lange wie möglich von niedrig zu bleiben Level-Thread-Management, da es wirklich schnell knifflig wird.

+0

Danke für die Antwort. Bitte sieh dir meinen Schnitt an. Ich interessiere mich speziell für die Methoden 'wait()' und 'notify()' in der Object-Klasse und möchte wissen, wann sie aufgerufen werden. – Omer

+0

Sie werden aufgerufen, wenn Sie sie anrufen, weshalb ich mich nicht sicher bin, ob es sich um einen Umbruch handelt.Ich denke, Sie versuchen zu überprüfen, wenn ein Thread nach einem Notify/NotifyAll-Aufruf ausgeführt wird, korrigieren Sie mich, wenn ich falsch liege, die ein viel breiteres Thema ist – Adonis

+0

Sie haben Recht, ich möchte ein Handle auf einem Thread, wenn es ausgeführt wird Zustand zu Wartezustand und umgekehrt. Der einzige Haken in den Code, den ich habe, sind die Debug-Anweisungen. Unter Berücksichtigung dieser Einschränkungen muss ich die Aufrufe von 'wait' und' notify' protokollieren – Omer

Verwandte Themen