我的 java 类启动时启动了 10 个线程,它们查看目录并开始查找文件。在我的一种方法中,我将 .txt 文件扩展名更改为 .working ,这表明文件当前正在处理中。当我的 java 类被调用或启动时,我有时会看到只有 5 个文件正在处理,因为它们的扩展名是 .working 。请让我知道我应该如何确保没有 2 个线程正在调用同一个 .txt 文件!
问问题
140 次
3 回答
4
最简单的方法是在一个线程中读取文件列表,然后使用线程安全的生产者/消费者队列(例如ArrayBlockingQueue
)发布这些“要处理的文件”。然后这十个线程将全部从同一个队列中取出项目,这确保没有项目被处理两次。
于 2012-05-07T19:10:35.527 回答
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);
}
于 2012-05-07T19:12:34.660 回答
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) {
}
于 2012-05-07T19:11:53.840 回答