Заблокируйте файл /"папку" для конкретной JVM и выполните итерацию, если заблокированы
Я использую несколько JVM, но мне нужно, чтобы каждая JVM использовала определенную папку. Я пытаюсь перебирать папки, пока не найдет файл, который не заблокирован, а затем заблокировать его для использования этой конкретной папки.
Здесь я фильтрую папки, которые хочу использовать:
// Filter 'fran' folders
String dir = System.getProperty("user.dir");
FilenameFilter filter = new FilenameFilter() {
public boolean accept(File dir, String name) {
String lowercaseName = name.toLowerCase();
if (lowercaseName.startsWith("fran")) {
return true;
} else {
return false;
}
}
};
File[] dirs = new File(dir).listFiles(filter);
Затем я пытаюсь пройти через папки и проверить, заблокирован ли он или нет с f.canWrite()
, Однако всегда используется только одна папка и игнорируются другие.
// Find available folder
boolean lock = true;
String lock_folder = "";
FileChannel fileChannel = null;
FileLock lockfile = null;
File f = null;
while (lock) {
for (File folder : dirs) {
f = new File(folder + "\\lock.txt");
Boolean isnotlocked = f.canWrite();
if (isnotlocked) {
fileChannel = new RandomAccessFile(f, "rw").getChannel();
lockfile = fileChannel.lock();
lock = false;
lock_folder = folder.getAbsolutePath();
break;
}
}
}
Ранее я пытался выполнить то, что мне было нужно, без FileLock, создав файл в определенной папке, а затем удалив его после завершения. Если в папке нет этого файла, она создаст и заблокирует эту JVM. Однако я думаю, что JVM были смешанными, потому что результаты были плохими.
Надеюсь, ты понимаешь, в чем моя проблема, буду очень признательна за помощь.
1 ответ
Вот несколько идей:
Предполагая класс процесса - CustomProcess.java
, Это работает в отдельном потоке. У класса есть конструктор, который принимает файловую папку в качестве аргумента. Давайте предположим, что filePath1
путь к папке и принимается от FileChooser
,
(а) Как работает приложение:
Поместите выбранную папку filePath1
в коллекции, как List<File>
или же List<Path>
- давайте назовем это processFilesList
; это общее (возможно, static
член) всеми процессами (это должна быть одновременная коллекция из java.util.concurrent
пакет). Этот список отслеживает папки, которые уже обрабатываются. Перед началом процесса проверьте, filePath1
уже в processFilesList
,
(б) Создать и запустить процесс:
CustomProcess p1 = new CustomProcess(filePath1);
p1.startProcess(); // here the application does whatever with the files in the folder.
Вариант 2:
Поместите все пути к файлам папок, которые должны быть обработаны в Queue
коллекция. Обрабатывайте каждую папку (и ее файлы по мере необходимости) по одному или несколькими процессами. Очередь может быть "первым пришел-первым обслужен" (FIFO) или "первым пришел-первым обслужен" (LIFO). Можно рассмотреть эти параллельные реализации очереди на основе требования: ConcurrentLinkedQueue
, LinkedBlockingQueue
, ConcurrentLinkedDeque
или же LinkedBlockingDeque
,