3

我想让我的线程(主/EDT)等到文件发生更改,然后等待。DefaultFileMonitor 扩展了 Runnable,因此在它自己的线程中运行。这是一个SSCE:

import java.io.File;
import org.apache.commons.vfs.*;
import org.apache.commons.vfs.impl.DefaultFileMonitor;

public class FileChangeListener implements FileListener {
    DefaultFileMonitor fm;
    public final static File logFile = new File("t.txt");

 public void startListening() throws FileSystemException {
    final FileSystemManager fsManager = VFS.getManager();
    final FileObject listendir = fsManager.toFileObject(logFile);

    fm = new DefaultFileMonitor(this);
    fm.addFile(listendir);
    fm.start();
}

     @Override
public void fileCreated(FileChangeEvent fce) throws Exception {
    fileChanged(fce);
}

@Override
public void fileDeleted(FileChangeEvent fce) throws Exception {
    //hmm..why deleted?
}

@Override
public void fileChanged(FileChangeEvent fce) throws Exception {
    System.out.println("fileChanged executed");
}
}

主要的:

import java.io.PrintWriter;

public class App {

public static void main(String[] args) {
    FileChangeListener fcl = new FileChangeListener();
    try {
        fcl.startListening();
        final PrintWriter printWriter = new PrintWriter(FileChangeListener.logFile);
        printWriter.println("Hello Threads!");
        printWriter.close();

        //EXECUTE THE FOLLOWING ONLY AFTER fileChanged
        System.out.println("Mission complete.");
    } catch (Exception ex) {
    }
}
}
4

3 回答 3

2

在 printWriter.close() 之后将以下内容附加到 App.main(..):

            synchronized (fcl) {
                fcl.wait();
            }
            //EXECUTE THE FOLLOWING ONLY AFTER fileChanged
            System.out.println("Mission complete.");

并在 System.out.println("fileChanged executed") 之后将以下内容附加到 FileChangeListener.fileChanged(..):

synchronized (this) {
        this.notifyAll();
    }
于 2010-11-08T16:08:51.813 回答
1

您可以使用“条件”在两者之间进行通信:http: //download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/locks/Condition.html

基本上,创建一个新的“共享” Condition(比如fileChanged)。现在,每当文件更改时(fileChanged()触发此条件(fileChanged.signal())。在您的主代码中,等待此条件发生(fileChanged.await())。

希望你能明白。


为了使多个代码单元可以访问该条件,这是我的想法(降低优先级):

  1. 假设您将需要与您所听的文件一样多的条件,请创建一个工厂方法getCondition(String file path/name/attribute),该方法将Condition根据文件(其路径或名称或其他属性)返回对象。使用此工厂方法获取所有情况下的条件。工厂应该在内部new Condition()为每个要收听的新文件创建实例,并且必须在文件处理完成时丢弃旧实例(因此您可能还应该添加一个destroy/deleteCondition(String file)方法。)
  2. 将条件作为public字段存储在侦听器类中(如果您有可用的侦听器实例,这是一种黑客行为)。
  3. 将条件作为public static字段存储在侦听器类中(如果您始终只有一个侦听器实例,这是一种黑客行为)。
于 2010-11-08T08:59:08.080 回答
0

为什么?FileChangeListener 是一个回调:在事件发生时执行。在这种特定情况下,您刚刚关闭了文件,因此您已经知道该文件上的任务已完成,因此请继续下一步。我不明白为什么你需要一个 FileChangeListener 在这里。

于 2010-11-08T09:28:20.383 回答