2

次のメソッドは、共有変数にアクセスしません。まだスレッドセーフではありません。テストが間違っているか、何かが欠けています。説明してください。

方法:

public static boolean acquireFolderLock(File directoryPath) {
    final String LOCK_FILE_NAME = ".lock";
    boolean isLocked = false;
    if(directoryPath != null && directoryPath.isDirectory()) {
        File lockFile = new File(new StringBuilder(directoryPath.getAbsolutePath()).append(File.separatorChar).append(LOCK_FILE_NAME).toString());
        if(lockFile.exists()) {
            isLocked = false;
        } else {
            try {
                lockFile.createNewFile();
                isLocked = true;
            } catch(IOException ioex) {
                isLocked = false;
            }
        }
    }
    return isLocked;
}

テスト用のスレッド クラス

class AThread extends Thread {
String name;
public AThread(String name) {
    this.name = name;
}

@Override
public void run() {
    File f = new File("C:\\TEMP\\DIRECTORY");
    System.out.println(name + ": " + Util.acquireFolderLock(f));
}
}

そして、スレッドを開始するメインメソッド

public static void main(String[] args) throws Exception {
    for(int i = 1; i <= 100; i++) {
        (new AThread("Thread-->" + i)).start();
    }
}
4

4 に答える 4

6

このメソッドは、ファイルが存在するかどうかを確認し、後で作成します。つまり、あるスレッドがステートメントif (lockFile.exists())(outcome: false) を実行しているときに、別のスレッドが実行している可能性がありlockFile.createNewFile();ます (したがって、ロック ファイルが作成されます)。

最初のスレッドは、誤った情報に基づいて続行しています。ファイルは存在しないと考えていますが、別のスレッドによって既に作成されています。

スレッド セーフは、共有変数だけではなく、共有リソース (変数、データベース、ファイル システム、ネットワーク接続など) に関するものです。

于 2012-04-06T22:08:04.497 に答える
3

「静的状態」とは、ファイル システムを含む用語です。変数が明示的に共有されていないからといって、ファイルシステムがスレッド間で共有されていないわけではありません。

ここで行っている方法でファイルシステムにアクセスすることは、共有変数にアクセスするのと同じくらい悪いことであり、スレッドセーフにするために同じ手法が必要です。

于 2012-04-06T22:06:25.363 に答える
0

lockFile.createNewFile()の戻り値を確認するためのものであり、lockFile.exists()を確認する必要はありません。

true if the named file does not exist and was successfully created; false if the named file already exists

また、ユースケースによっては、nioFileLockはcreateNewFileを使用するよりも信頼性が低い場合があります。私はnioFileLockがNFS上で壊れていると思います。javadocsが信頼できないとはどういう意味かはわかりませんが、createNewFileの問題の1つは、クラッシュしたときにロックを解除することです。ただし、ユースケースによっては、これはバグではなく機能になる可能性があります。

于 2012-04-06T23:08:46.130 に答える
0

File.createNewFile() の javadocs によるとhttp://docs.oracle.com/javase/6/docs/api/java/io/File.html#createNewFile ()

注: この方法はファイルのロックには使用しないでください。結果として得られるプロトコルを確実に機能させることはできません。代わりに FileLock 機能を使用する必要があります。

したがって、スレッドセーフな java.nio.channels.FileLock を使用する必要があります。

于 2012-04-06T22:11:16.457 に答える