2

Javaクラスの開始時に開始されるスレッドが10個あり、それらはディレクトリを調べてファイルの検索を開始します。私の方法の1つで、.txtファイルの拡張子を.workingに変更します。これは、ファイルが現在処理中であることを示します。私のJavaクラスが呼び出されたり開始されたりすると、拡張子が.workingであるため、5つのファイルしか処理されていないことがあります。2つのスレッドが同じ.txtファイルを呼び出していないことを確認する方法を教えてください!!

4

3 に答える 3

4

最も簡単なアプローチは、1つのスレッドでファイルのリストを読み取り、スレッドセーフなプロデューサー/コンシューマーキュー(例ArrayBlockingQueue)を使用して、これらの「処理するファイル」を公開することです。その後、10個のスレッドはすべて同じキューからアイテムを削除します。これにより、アイテムが2回処理されることはありません。

于 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 に答える