⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 driver.java

📁 一个类似于openJMS分布在ObjectWeb之下的JMS消息中间件。
💻 JAVA
字号:
/* * Copyright (C) 2001 - 2006 ScalAgent Distributed Technologies * Copyright (C) 1996 - 2000 BULL * Copyright (C) 1996 - 2000 INRIA * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or any later version. *  * This library is distributed in the hope that it will be useful, * but 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. *  * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 * USA. */package fr.dyade.aaa.agent;import java.io.*;import java.util.*;import fr.dyade.aaa.util.*;import org.objectweb.util.monolog.api.BasicLevel;import org.objectweb.util.monolog.api.Logger;/** * Internal class to catch the end of the thread running the driver. */class ThreadFinalizer implements Runnable {  /** driver to start */  Driver driver;  /**   * Allocates a new daemon for specified driver.   *   * @param driver	driver to start   */  ThreadFinalizer(Driver driver) {    this.driver = driver;  }  /**   * Starts the driver. Catches the driver thread termination and calls   * the driver <code>end</code> function.   */  public void run() {    try {      driver.logmon.log(BasicLevel.DEBUG,                        driver.getName() + " start");      driver.run();      driver.canStop = false;    } catch (ThreadDeath death) {      // the thread has been killed, prints no error message      throw death;    } catch (Throwable exc) {      driver.canStop = false;      driver.logmon.log(BasicLevel.ERROR,                        driver.getName() + " failed", exc);    } finally {      driver.canStop = false;      driver.reset();      if (!Thread.interrupted()) {        driver.logmon.log(BasicLevel.DEBUG, driver.getName() + "end");      }      driver.end();    }  }}/** * Abstract base class for drivers such as <code>DriverIn</code> used by * <code>ProxyAgent</code>. * <p> * Multithreading in the agent server is special, as the code executed * outside of the main engine thread is no longer part of a transaction. * The class <code>Driver</code> has been designed to help programming in * a separate thread in the agent server. * <p> * A key difference between the main thread and a driver thread is the semantics * of sending a notification. When in the main thread of the agent server, * a notification is sent as part of an agent reaction. It is then part of * a transaction, and is actually sent only when the transaction commits. * When in a separate thread, the <code>directSendto</code> function of class * <code>Channel</code> is used instead, actually creating a new transaction * for the single purpose of sending the notification. When the function returns * the notification sending has been committed. The function <code>sendTo</code> * in this class encapsulates the call to the special <code>Channel</code> * function, and should be used by derived classes. * <p> * This class is designed to be derived. Derived classes should define the * function <code>run</code>, providing the actual code to be executed in the * separate thread, and may define the function <code>end</code>, providing * finalizing code executed when the thread terminates. The <code>end</code> * function is always called, even when the <code>run</code> function raises * an exception. */public abstract class Driver {  /** separate thread running the driver */  protected Thread thread;  /** identifier local to the driver creator */  protected int id;  /**   * Boolean variable used to stop the driver properly. If this variable is   * true then it indicates that the driver is stopping.   */   public volatile boolean isRunning = false;  public volatile boolean canStop = false;  protected Logger logmon = null;  protected String name = null;  protected static Hashtable drivers = new Hashtable();  /**   * Constructor.   *   * @param id		identifier local to the driver creator   */  protected Driver(int id) {    thread = null;    this.id = id;    isRunning = true;    // Get the logging monitor from current server MonologLoggerFactory    // It should be overloaded in subclass in order to specialize traces.    String classname = getClass().getName();    logmon = Debug.getLogger(Debug.A3Proxy + '.' +      classname.substring(classname.lastIndexOf('.') +1));    this.name = classname + '#' + id;  }  /**   * Constructor with default id.   */  protected Driver() {    this(0);    isRunning =true;  }  /**   * Returns name of driver, actually classname and driver id. It should   * be overloaded in subclass to take in account the proxy name.   */  public String getName() {    return name;  }  /**   * Provides a string image for this object.   *   * @return	printable image of this object   */  public String toString() {    return "(" + getClass().getName() +      ",name=" + getName() +      ",id=" + id + ")" +      ",isRunning=" + isRunning +      ",canStop=" + canStop;  }  /**   * Actually executes the driver code.   * To be defined in derived classes.   * <p>   * Beware: this code is executed in a separate thread, outside from any   * transaction. Notifications may be sent using function <code>sendTo</code>,   * and they will actually be sent as soon as the function is called; there is   * no atomic treatment as there is in an agent reaction.   *   * @exception Exception   *	unspecialized exception   */  public abstract void run() throws Exception;  /**   * Finalizes driver; called in <code>finally</code> clause of driver thread.   * May be overloaded in derived classes.   */  protected void end() {}  /**   * Starts the driver execution.   */  public void start() {    thread = new Thread(new ThreadFinalizer(this), getName());    thread.setDaemon(true);    drivers.put(this, this);    thread.start();  }  /**   * Nullify thread variable. To be used by ThreadFinalizer.   */  synchronized void reset() {    thread = null;    drivers.remove(this);  }  /**   * Stops the driver execution.   */  public synchronized void stop() {    if (thread == null) return;    isRunning = false;    if (canStop) {      thread.interrupt();      close();    }    thread = null;  }  public abstract void close();  static void stopAll() {    Logger logmon = Debug.getLogger(Debug.A3Proxy);    if ((drivers == null) || (drivers.size() == 0)) return;    Driver[] tab = (Driver[]) (drivers.values().toArray(new Driver[0]));    for (int i=0; i<tab.length; i++) {      logmon.log(BasicLevel.WARN, tab[i].getName() + " " + tab[i].isRunning + "/" + tab[i].canStop + " stop()");      tab[i].stop();    }  }   /**   * Sends a notification to an agent.   * <p>   * Provides a similar function as the <code>sendTo</code> function in   * <code>Agent</code> class, except that the notification is sent directly   * via a <code>directSendTo</code> method.   *   * @param to		target agent   * @param not		notification to send   */  protected final void sendTo(AgentId to, Notification not) throws IOException {    Channel.sendTo(to, not);  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -