如何让我的方法在继续之前等待文件存在

10

有一个外部程序会创建一个XML文件,但可能需要一段时间来完成。我需要我的Java程序在继续执行之前等待文件存在。

我已经阅读了一些关于synchronized块的内容,并且我知道我可以做类似于下面这样的事情:

synchronized(this) {
    while (!file.exists) { this.wait(); }
}

说实话,我对同步任务并不是很了解,所以我想知道我是否走在了正确的轨道上,或者我完全错了。


在wait(long timeout)中设置一些超时时间,以便在同样的时间后线程会被唤醒。 - Prashant
5
不,这完全不是它的工作原理,忘记synchronized。你可以选择:1)等待程序完成,或在程序写入文件时从程序中写入stdout; 或者2)使用WatchService跟踪目录更改。 - Boris the Spider
1
首先,synchronized 与多线程程序有关。其次,外部程序是独立于您的Java程序运行的,还是您的Java程序启动了这个外部程序? - Alexander R.
外部程序独立于我的Java程序运行。 - namxal
3
请注意,“存在”和“完全写入”是两回事。通常情况下,您无法一次性编写文件,因此需要同时检查文件是否存在以及进程是否不再向其中写入。 - Colonel Thirty Two
4个回答

4
一种解决此问题的典型方法是让您的XML编写者创建XML文件,当它完成时,应创建第二个文件表示工作已完成。
您的Java程序应监听.done文件的存在而不是XML文件。
如果您无法控制XML编写应用程序,则无法起作用。

0

0
所以我选择了一个while循环来检查文件是否不存在。如果不存在,我会让线程休眠一秒钟。这似乎正常工作。谢谢你的帮助。

2
我建议您研究事件驱动方法,例如WatchService,而不是循环轮询方法。摆脱古老且大多数人不赞成的习惯对您有好处。 - Boris the Spider
1
是的,我也不喜欢轮询方法。我会看一下WatchService。 - namxal
1
@namxal,你能提供这个代码吗?你是如何让线程休眠的? - chaviaras michalis

-4
在我看来,你应该有一些东西来通知线程。以下是我的示例。
public class Test {
File file;
public Test(File file){
    this.file = file;
}

public void findFile(){
    synchronized(this){
        while(!file.exists()){
            try {
                System.out.println("before wait:");
                this.wait();
                System.out.println("after wait:");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

public void createFile(){
    synchronized(this){
        try {
            System.out.println("before create a new file:");
            file.createNewFile();
            System.out.println("after create a new file:");
            this.notify();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

public static void main(String[] args){ 
    Test t = new Test(new File("/Users/yehuizhang/Desktop/uttp.txt"));
    Thread t1 = new Thread(new FindFile(t));
    Thread t2 = new Thread(new CreateFile(t));
    t1.start();
    t2.start();
}
}

class FindFile implements Runnable{
Test t;
public FindFile(Test t){
    this.t = t;
}

@Override
public void run(){
    t.findFile();
}
}

class CreateFile implements Runnable{
Test t;

public CreateFile(Test t){
    this.t = t;
}

@Override
public void run(){
    t.createFile();
}
}

@ColonelThirtyTwo Thirty Two,它运行良好。结果是 等待之前: 创建新文件之前: 创建新文件之后: 等待之后: - uttp
1
等什么?createFile在外部程序中,无法通知findFile线程。 - Colonel Thirty Two
@ColonelThirtyTwo 当两个线程使用一个“Test”实例时,“createFile”可以注意到“findFile”。你没有理解我的代码。 - uttp
我的意思是你的代码并不能代表这个问题。原帖中在第一句话就提到了文件是在一个外部进程中创建的,而该进程无法使用 Object.notify - Colonel Thirty Two

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接