不确定我的10个线程在启动时是否正在读取相同的.txt文件

时间:2012-05-07 19:08:46

标签: java multithreading

我有10个线程在我的java类启动时启动,它们会查看目录并开始查找文件。在我的一个方法中,我将.txt文件扩展名更改为.working,表示文件当前正在处理中。当我的java类被调用或启动时,我发现有时只有5个文件正在被处理,因为它们的扩展名是.working。请告诉我如何确保没有2个线程调用相同的.txt文件!

3 个答案:

答案 0 :(得分:4)

最简单的方法是读取一个线程中的文件列表,然后使用线程安全的生产者/消费者队列(例如ArrayBlockingQueue)来发布这些“要处理的文件” 。然后,十个线程将所有项目从同一队列中取出,这确保没有项目被处理两次。

答案 1 :(得分:1)

您可能遇到类似于以下伪代码的竞争条件。多个线程将进行存在测试,然后尝试重命名并处理相同的文件。

File file = new File("file.txt");
File working = new File("file.working");
if (file.exists()) {
   // race condition may happen at this point
   file.renameTo(working);
   processWorking(working);
}

您应该围绕测试进行同步并重命名。类似的东西:

private final Object lockObject = new Object();
...

boolean process = false;
// lock around the test and the rename
synchronized (lockObject) {
    if (file.exists()) {
       file.renameTo(working);
       process = true;
    }
}
// process the file outside of the lock
if (process) {
    processWorking(working);
}

答案 2 :(得分:0)

您可以在线程程序中使用以下代码。

 try {
        // Get a file channel for the file
        File file = new File("filename");
        FileChannel channel = new RandomAccessFile(file, "rw").getChannel();

        // Use the file channel to create a lock on the file.
        // This method blocks until it can retrieve the lock.
        FileLock lock = channel.lock();

        // Try acquiring the lock without blocking. This method returns
        // null or throws an exception if the file is already locked.
        try {
            lock = channel.tryLock();
        } catch (OverlappingFileLockException e) {
            // File is already locked in this thread or virtual machine
        }

        // Release the lock
        lock.release();

        // Close the file
        channel.close();
    } catch (Exception e) {
    }