我们在Jboss 6.4中有一个Web应用程序,它必须检查Folder(new Files),我们的想法是将Commons IO 2.4与FileAlterationMonitor一起使用,就像我们想要控制监视器的备份一样。如果工作正常,

为此,我们创建了一个TimerTask来控制它是否正在运行的线程(如果没有运行),创建另一个观察器以继续工作。

我们的问题:

现在在测试中,我们引发了一个异常,以杀死观察者,并检测该观察者是否不工作,然后再次重新启动,但是我们不知道我们该如何在FileAlterationMonitor,FileAlterationObserver或FileAlterationListener中执行此操作,以及如何?

public class App {

  private static final String FOLDER ="/Folder";
  private static final FileAlterationMonitor monitor = new FileAlterationMonitor(1000);

  public static void main(String[] args) throws Exception {

    final File directory = new File(FOLDER);
    FileAlterationObserver fao = new FileAlterationObserver(directory);
    fao.addListener(new FileAlterationListenerImpl());
    monitor.addObserver(fao);

    monitor.start();


      TimerTask task = new TimerTask() {
          @Override
          public void run() {
            System.out.println("Monitor Controler");

            ThreadGroup currentGroup = Thread.currentThread().getThreadGroup();
            int noThreads = currentGroup.activeCount();
            Thread[] lstThreads = new Thread[noThreads];
            currentGroup.enumerate(lstThreads);

            for (int i = 0; i < noThreads; i++) {
                System.out.println("Thread No:" + i + " = "+ lstThreads[i].getName());
                System.out.println(lstThreads[i].getState().toString());
                System.out.println(lstThreads[i].isInterrupted());
                System.out.println(lstThreads[i].isAlive());
            }

                for (FileAlterationObserver o :monitor.getObservers()) {
                    String obName = o.toString();
                    String obDir = o.getDirectory().toString();

                    for(FileAlterationListener l :o.getListeners()){
                      String listener = l.toString();

                    }

          }
        };

        Timer timer = new Timer();
        long delay = 0;
        long intevalPeriod = 1 * 1000;

        // schedules the task to be run in an interval
        timer.scheduleAtFixedRate(task, delay, intevalPeriod);

  }

}


我的解决方案:

   public class App {

  private static final String FOLDER = "/Folder/";
  private static final FileAlterationMonitor monitor = new FileAlterationMonitor(1000);


  public static void main(String[] args) throws Exception {

    final File directory = new File(FOLDER);
    FileAlterationObserver fao = new FileAlterationObserver(directory);
    fao.addListener(new FileAlterationListenerImpl());

    monitor.addObserver(fao);
    monitor.start();

      TimerTask task = new TimerTask() {
          @Override
          public void run() {

            ThreadGroup currentGroup = Thread.currentThread().getThreadGroup();
            int noThreads = currentGroup.activeCount();
            Thread[] lstThreads = new Thread[noThreads];
            currentGroup.enumerate(lstThreads);

            boolean isDead = true;
            for (int i = 0; i < noThreads; i++) {

//              System.out.println("Thread No:" + i + " = "+ lstThreads[i].getName());
//              System.out.println("getState: "+lstThreads[i].getState().toString());
//              System.out.println("isInterrupted: "+ lstThreads[i].isInterrupted());
//              System.out.println("isAlive: "+lstThreads[i].isAlive());

                if(lstThreads[i].getName().equals("monitorThread"))
                {
                    isDead= false;
                }
            }

            if(isDead){
                try {
                    monitor.stop();
                    monitor.start();
                    isDead = false;
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }

          }
        };

        Timer timer = new Timer();
        long delay = 0;
        long intevalPeriod = 1 * 1000;

        timer.scheduleAtFixedRate(task, delay, intevalPeriod);

  }

}


在我的FileAlterationListenerImpl中:

@Override
    public void onStart(final FileAlterationObserver observer) {

        Thread.currentThread().setName("monitorThread");


是我唯一可以设置线程名称的地方。

最佳答案

您可以在FileAlterationMonitor上使用setThreadFactory()方法来设置自定义线程工厂。要了解运行监视器的线程的状态,我们需要访问其实例。

因此,如下创建一个自定义的ThreadFactory类。

class SimpleThreadFactory implements ThreadFactory {
    private Thread monitorThread;
    public Thread newThread(Runnable r) {
        Thread thread = new Thread(r);
        if( r instanceof FileAlterationMonitor) {
            monitorThread = thread;
        }

        return thread;
    }

    public boolean isMonitorThreadAlive() {
        boolean isAlive = false;
        if(monitorThread != null) {
            isAlive = monitorThread.isAlive();
        }
        return isAlive;
    }
}


现在,使用setThreadFactory()上的FileAlterationMonitor设置上述自定义线程工厂。

然后,您可以使用自定义isMonitorThreadAlive()方法检查它是否仍然存在。

另一种粗略但可能更简单的方法是为监视线程命名,并使用top ThreadGroup通过给定名称查找线程(并在其上使用isAlive())。

以下是一个简单的示例

#Edit:以下内容不能用作FileAlterationMonitor,这是@JOANA_Batista指出的最终类

FileAlterationMonitor monitor = new FileAlterationMonitor(directory) {
    @Override
    public void run () {
        //setting name
        Thread.currentThread().setName("monitorThread");
        this.run();
    }
}


由于无法覆盖FileAlterationMonitor,因此必须找到其他方法来更改监视器线程名称。我们可以设置使用FileAlterationListener.onStart()

由于此方法是在FileAlterationObserver.checkAndNotify()中调用的FileAlterationMonitor.run()上调用的

FileAlterationMonitor.run()

public void run() {
    while (running) {
        for (FileAlterationObserver observer : observers) {
            observer.checkAndNotify();
        ...


FileAlterationObserver.checkAndNotify()

public void checkAndNotify() {

    /* fire onStart() */
    for (FileAlterationListener listener : listeners) {
        listener.onStart(this);
    }
    ...


这一切都发生在同一监视器线程上,这就是以下代码应在FileAlterationListener.onStart()中设置监视器线程名称的原因

@Override
void onStart(final FileAlterationObserver observer) {
    Thread.currentThread().setName("monitorThread");
    ...
}


注意:您可以在FileAlterationMonitor上调用stop()方法来停止()线程,但是要再次启动它,您必须再次添加新的FileAlterationObserver,因为stop方法会破坏观察者。这实际上应该重新启动监视器线程。

public synchronized void stop(long stopInterval) throws Exception {
    if (running == false) {
        throw new IllegalStateException("Monitor is not running");
    }
    running = false;
    try {
        thread.join(stopInterval);
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
    /***** Observers are destroyed here ****/
    for (FileAlterationObserver observer : observers) {
        observer.destroy();
    }
}


最好在调用stop之后再创建所有内容(侦听器,监控器和Obsever),因为没有太多可重用的内容(仅Monitor对象)。

关于java - Commons IO 2.4,如何控制FileAlterationListener的状态并重启,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36673817/

10-10 19:34