Logo
Distributed Genetic Programming Framework
print print

File org.sfc.parallel.SfcThread.java

Here you can find all the information about the file org.sfc.parallel.SfcThread.java. You may explore it here or download it onto your local disk.
/*
 * Copyright (c) 2005 Thomas Weise
 *
 * E-Mail           : tweise@gmx.de
 * Creation Date    : 2005-09-01 10:42:10
 * Original Filename: org.sfc.parallel.SfcThread.java
 * Version          : 3.2.0
 * Last modification: 2006-06-08
 *                by: Thomas Weise
 *
 * License          : GNU LESSER GENERAL PUBLIC LICENSE
 *                    Version 2.1, February 1999
 *                    You should have received a copy of this license along
 *                    with this library; if not, write to the Free Software
 *                    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *                    MA 02111-1307, USA or download the license under
 *                    http://www.gnu.org/copyleft/lesser.html.
 *
 * Warranty         : This software is provided "as is" without any
 *                    warranty; without even the implied warranty of
 *                    merchantability or fitness for a particular purpose.
 *                    See the Gnu Lesser General Public License for more
 *                    details.
 */


package org.sfc.parallel;



import org.sfc.events.ErrorEvent;
import org.sfc.events.IEventListener;
import org.sfc.parallel.events.ParallelStateEvent;


/**
 * This class is the base of all sfc threads, except the serialized thread,
 * which is only to be used as shutdown-hook.
 *
 * @author Thomas Weise
 */

public abstract class SfcThread extends     Thread
                                implements  IWaitable, IAbortable,
                                            IStartable
  {
/**
 * The internal uncaught exception handler.
 */

  private static  final UncaughtExceptionHandler  EXCEPTION_HANDLER =
    new UncaughtExceptionHandler()
    {
    public  final void uncaughtException(final  Thread    p_thread,
                                         final  Throwable p_error)
      {
      SfcThread l_stf;

      l_stf = ((SfcThread)p_thread);
      try
        {
        l_stf.do_error(p_error);
        }
      finally
        {
        l_stf.dead();
        }
      }
    };

/**
 * The internal sync object.
 */

  private final     SyncPoint                 m_sync  ;
/**
 * 0 if the thread wasnt started yet, 1 if it runs, 2 if it has terminated.
 */

  private volatile  byte                      m_state ;
/**
 * The user-provided uncaught exception handler.
 */

  private volatile  UncaughtExceptionHandler  m_handler ;

/**
 * The event propagator.
 */

  private final     IEventListener           m_events  ;

/**
 * Create a new sfc thread.
 * @param p_group The sfc-thread group owning this thread. This can be
 *                <code>null</code>.
 */

  public  SfcThread (final  SfcThreadGroup p_group)
    {
    this(p_group, null);
    }

/**
 * Create a new sfc thread.
 * @param p_events  The event propagator to be used internally.
 */

  public  SfcThread (final IEventListener  p_events)
    {
    this(null, p_events);
    }

/**
 * Create a new sfc thread.
 * @param p_group The sfc-thread group owning this thread. This can be
 *                <code>null</code>.
 * @param p_events  The event propagator to be used internally.
 */

  public  SfcThread (final SfcThreadGroup   p_group,
                           IEventListener  p_events)
    {
    super(p_group, (Runnable)null);
    ThreadGroup l_t;

    if(p_events == null)
      {
      l_t = this.getThreadGroup();
      if(l_t instanceof SfcThreadGroup)
        {
        p_events = ((SfcThreadGroup)l_t).get_propagator();
        }
      }

    this.m_events = p_events;
    this.m_sync   = new SyncPoint(false);
    super.setUncaughtExceptionHandler(EXCEPTION_HANDLER);
    }


/**
 * Set the handler invoked when this thread abruptly terminates
 * due to an uncaught exception.
 * <p>A thread can take full control of how it responds to uncaught
 * exceptions by having its uncaught exception handler explicitly set.
 * If no such handler is set then the thread's <tt>ThreadGroup</tt>
 * object acts as its handler.
 * @param p_eh the object to use as this thread's uncaught exception
 * handler. If <tt>null</tt> then this thread has no explicit handler.
 * @throws  SecurityException  if the current thread is not allowed to
 *          modify this thread.
 * @see ThreadGroup#uncaughtException
 */

  @Override
  public synchronized final  void setUncaughtExceptionHandler(
                        final  UncaughtExceptionHandler p_eh)
    {
    this.m_handler = p_eh;
    }

/**
 * Returns the handler invoked when this thread abruptly terminates
 * due to an uncaught exception. If this thread has not had an
 * uncaught exception handler explicitly set then this thread's
 * <tt>ThreadGroup</tt> object is returned, unless this thread
 * has terminated, in which case <tt>null</tt> is returned.
 * @return  The uncaught exception handler.
 */

  @Override
  public synchronized final UncaughtExceptionHandler
                                  getUncaughtExceptionHandler()
    {
    if(this.m_state >= 2) return null;
    if(this.m_handler != null) return this.m_handler;
    return this.getThreadGroup();
    }


/**
 * This method will be called on error.
 * Override it to provide additional behavior.
 * @param p_throwable         The error catched.
 */

  protected void  on_error  (final  Throwable p_throwable)
    {
    //
    }

/**
 * This method will be internally called on error.
 * To provide additional behavior, see <code>on_error</code>.
 * @param p_throwable         The error catched.
 * @see #on_error(Throwable)
 */

  final void  do_error(final  Throwable p_throwable)
    {
    UncaughtExceptionHandler  l_h;

    l_h = this.m_handler;
    if(l_h != null)
      {
      try
        {
        l_h.uncaughtException(this, p_throwable);
        }
      catch(Throwable l_t)
        {
        //
        }
      }

    if(this.m_events != null)
      {
      this.m_events.receive(new ErrorEvent(this, p_throwable));
      }

    this.on_error(p_throwable);
    }

/**
 * Start this thread.
 */

  @Override
  public  final   void start()
    {
    ThreadGroup l_tg;

    synchronized(this.m_sync)
      {
      if(this.m_state != 0) return;
      this.m_state = 1;
      
      this.m_sync.set_wait(true);
      }
    
    l_tg = this.getThreadGroup();
    if(l_tg instanceof SfcThreadGroup)
      {
      ((SfcThreadGroup)l_tg).register();
      }
    
    if(this.m_events != null)
      {
      this.m_events.receive(new ParallelStateEvent(this, true));
      }

    synchronized(this)
      {
      this.do_start();
      }
    
    super.start();
    }
  
/**
 * This method is called by <code>start()</code> before the thread begins
 * its work.
 * @see #start()
 */

  protected void  do_start()
    {
    //
    }

/**
 * This method must be overriden to contain the thread's code. It will be
 * executed in a loop as long as it returns <code>true</code> and throws
 * <b>no</b> <code>Throwable</code>.
 * @return  <code>true</code> if this method should be executed again.
 * @throws  Throwable Whenever it likes to, however, the execution loop
 *                    will be stopped when something is thrown.
 */

  protected abstract  boolean do_run  ()  throws Throwable;



/**
 * The original run method.
 */

  @Override
  public  final void  run ()
    {
    try
      {
      while((this.m_state == 1) && this.do_run())
        {
        //
        }
      }
    catch(Throwable l_t)
      {
      this.do_error(l_t);
      }
    finally
      {
      this.dead();
      }
    }

/**
 * This method is called when the thread terminates.
 */

  final void  dead ()
    {
    ThreadGroup l_tg;

    if(this.m_events != null)
      {
      this.m_events.receive(new ParallelStateEvent(this, false));
      }
      
    l_tg = this.getThreadGroup();
    if(l_tg instanceof SfcThreadGroup)
      {
      ((SfcThreadGroup)l_tg).unregister();
      }
        
    synchronized(this.m_sync)
      {
      this.m_state = 2;      
      }
      
    try
      {
      synchronized(this)
        {
        this.after_termination();
        }
      }
    finally
      {    
      this.m_sync.release(false);
      }
    }

/**
 * Override this method to perform something when the thread dies.
 */

  protected void  after_termination ()
    {
    //
    }



/**
 * Wait for this object.
 */

  public  final void  wait_for  ()
    {
    if(this != Thread.currentThread()) this.m_sync.wait_for();
    }

/**
 * Returns <code>true</code> if and only if this thread is currently
 * performing its task.
 * @return  <code>true</code> as long as this thread is running.
 */

  public  final boolean is_running  ()
    {
    return (this.m_state == 1);
    }

/**
 * This method is called by <code>abort()</code> to perform some work before
 * halting the thread.
 * @see #abort()
 */

  protected void  do_abort()
    {
 //   
    }
  
/**
 * Tells the thread to stop its actions. This is the proper method to allow
 * the thread to terminate itself. This method does not block.
 * @see #abort_and_wait()
 */

  public  final void  abort ()
    {
    synchronized(this.m_sync)
      {
      if(this.m_state > 1) return;
      this.m_state = 2;
      }
    this.safe_interrupt();
    
    synchronized(this)
      {
      this.do_abort();
      }
    }

/**
 * Tells the thread to stop its actions. This is the proper method to allow
 * the thread to terminate itself. This method does block until the thread
 * finished its activity.
 * @see #abort()
 */

  public  final void  abort_and_wait  ()
    {
    this.abort();
    this.wait_for();
    }

/**
 * Returns the hash-code of this thread.
 * @return The hash-code of this thread.
 */

  @Override
  public  final int hashCode  ()
    {
    return super.hashCode();
    }


/**
 * Obtain the event propagator of this thread. You can use it to propagate
 * error events.
 * @return  The event propagator of this thread.
 */

  protected final IEventListener get_listener  ()
    {
    return this.m_events;
    }

/**
 * Put the thread to sleep for approximately the specified amount of time.
 * It is not guaranteed that the whole time will be slept properly.
 * A call to this method might be interrupted by a call to
 * <code>safe_interrupt()</code>.<br/>
 * This method must only be called from within the thread's
 * <code>do_run</code> method.
 * @param p_time    The amount of time to sleep.
 * @return  <code>true</code> if and only if this thread is still running,
 *          <code>false</code> otherwise.
 * @see #safe_interrupt()
 * @see #do_run()
 */

  protected final boolean  safe_sleep (final long p_time)
    {
    try
      {
      synchronized(this.m_sync)
        {
        if(this.m_state == 1) this.m_sync.wait(p_time);
        }
      }
    catch(InterruptedException l_ie)
      {
      //
      }

    return (this.m_state == 1);
    }

/**
 * Safely interrupts the current thread. This will end any pending call to
 * <code>safe_sleep</code>.
 * @see #safe_sleep(long)
 */

  public  final void  safe_interrupt  ()
    {
    synchronized(this.m_sync)
      {
      this.m_sync.notifyAll();
      }
    }

/**
 * Obtain the name of the thread.
 * @return  A human readable name of the sfc thread.
 */

  @Override
  public  abstract  String  toString();
  }

File Information:

file name:SfcThread.java
package:org.sfc.parallel
qualified name:org.sfc.parallel.SfcThread.java
file type:Java Source File
download location:download http://dgpf.sourceforge.net/source/org/sfc/parallel/SfcThread.java
size:11.392 KB (11666 B)
uploaded: 2015-07-22 04:11:12 GMT+0000
last update: 2006-06-08 02:57:42 GMT+0000
last access: 2018-01-22 23:58:55 GMT+0000

statistics online since 2006-01-02.   RSS Feed
Contact us by sending an email to tweise@gmx.de to receive further information, to report errors, or to join our project.
All content on this site (http://dgpf.sourceforge.net/) is LGPL-licensed.
http://dgpf.sourceforge.net/scripts/source/source.php last modified at 2015-07-22 04:10:53 GMT+0000 served at 2018-01-22 23:58:55 GMT+0000.
Valid CSS Valid XHTML 1.1
Valid RSS SourceForge.net Logo