пятница, 8 марта 2013 г.

Event Waiter

Needed a possibility to notify a thread about event occurred in anothre thread. Originally other attemps were made to organize the necessary approach inside that threads but then idea came up to use a separate object for this kind of synchronization and it finally came out as pretty intelegent light easy to read approach so good that I wanted to share it with you.

/**
 * Event Waiter object is to synchronize one or several threads with a thread-event originator</br>
 * Thread safe.</br>
 * Actors: event originator thread and one or more event waiter thread(s)</br>
 * Event Waiter thread(s) must call {@link #waitForEvent()} to wait for the Event to occur</br>
 * Event Originator thread must call {@link #eventOccurred()} to notify that the Event has been occurred</br>
 * If the Event has been occurred waiter thread(s) are not blocked on {@link #waitForEvent()} call</br>
 * If the Event has not been occurred yet waiter thread(s) are blocked on {@link #waitForEvent()} call until the Event has occurred</br>
 
 @author vtkachenko
 *
 */
public class EventWaiter {

  private boolean eventOccurred = false;

  /**
   * Once the event has been occurred this method should be called to notify that
   */
  public synchronized void eventOccurred() {
    eventOccurred = true;
    notifyAll();
  }

  /**
   * Method to wait for the event to occur
   @throws InterruptedException
   */
  public synchronized void waitForEvent() throws InterruptedException {
    if (!eventOccurred) {
      wait();
    }
  }
}

And usage example.

public class EventWaiterTest {
  
  private static void waitedFirstTest() {
    
    System.out.println("waitedFirstTest begin");
    
    final EventWaiter eventWaiter = new EventWaiter();
    
    Thread threadWithEvent = new Thread(new Runnable() {
      @Override
      public void run() {
        try {
          Thread.sleep(1000);
        catch (InterruptedException e) {
          e.printStackTrace();
        }

        System.out.println("occurring the event...");
        eventWaiter.eventOccurred();
      }
    });
    threadWithEvent.start();
    
    try {
      System.out.println("waiting for the event...");
      eventWaiter.waitForEvent();
      System.out.println("event occurred");
    catch (InterruptedException e) {
      e.printStackTrace();
    }
    
    System.out.println("waitedFirstTest end");
  }
  
  private static void waitedLastTest() {
    
    System.out.println("waitedLastTest begin");
    
    final EventWaiter eventWaiter = new EventWaiter();
    
    Thread threadWithEvent = new Thread(new Runnable() {
      @Override
      public void run() {
        System.out.println("occurring the event...");
        eventWaiter.eventOccurred();
      }
    });
    threadWithEvent.start();

    try {
      Thread.sleep(1000);
    catch (InterruptedException e) {
      e.printStackTrace();
    }
    
    try {
      System.out.println("waiting for the event...");
      eventWaiter.waitForEvent();
      System.out.println("event occurred");
    catch (InterruptedException e) {
      e.printStackTrace();
    }
    
    System.out.println("waitedLastTest end");
  }

  /**
   @param args
   */
  public static void main(String[] args) {
    waitedFirstTest();
    waitedLastTest();
  }

}


Java HTML generated using Java2html