0

次のJavaコードは、Windowsで開いていないファイルの排他ロックを保証しますか?

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class Test {
    public static void main(String[] args) {
        File file = new File("mylog.log");
        try {
            FileOutputStream fos = new FileOutputStream(file);
            fos.getChannel().lock();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
4

3 に答える 3

1

Javaの仕様に見られるように:

ファイルロックは、Java仮想マシン全体に代わって保持されます。同じ仮想マシン内の複数のスレッドによるファイルへのアクセスを制御するのには適していません。

したがって、スレッド専用のロックが必要な場合は、別の方法を選択してください。

于 2010-07-08T12:08:13.017 に答える
1

tl; dr:いいえ。ホストオペレーティングシステムによるロックの処理の動作について推測することはできません。

良いニュース:アプリケーション内にスレッドセーフなロックメカニズムがあることを確認しようとしていますか?もしそうなら、それでFileLock十分です(もちろん、アプリケーションの残りの部分が適切に記述されたスレッドセーフコードで構成されていると仮定します)。

悪いニュース:残念ながら、Windowsがすべてのアプリケーションに対するロックを確実に尊重しようとしている場合、それを当てにすることはできません。

これはWindowsで簡単に確認できます。書き込み中のファイルを上書きできることがよくあります(たとえば、ログファイルが長くなりすぎると、emacsが以前のすべてのスパムを切り刻むようになります)。そうは言っても、Windowsは通常、開いているファイルを削除することを許可しません。

FileLockのドキュメントから

ファイルロックは、Java仮想マシン全体に代わって保持されます。同じ仮想マシン内の複数のスレッドによるファイルへのアクセスを制御するのには適していません。

ファイルロックオブジェクトは、複数の同時スレッドで安全に使用できます。

... 以降 ...

ロックが実際に別のプログラムがロックされた領域のコンテンツにアクセスするのを妨げるかどうかは、システムに依存するため、指定されていません。一部のシステムのネイティブファイルロック機能は単なる助言です。つまり、プログラムは、データの整合性を保証するために、既知のロックプロトコルを協調的に監視する必要があります。他のシステムでは、ネイティブファイルロックが必須です。つまり、1つのプログラムがファイルの領域をロックすると、他のプログラムがロックに違反する方法でその領域にアクセスできなくなります。さらに他のシステムでは、ネイティブファイルロックがアドバイザリであるか必須であるかは、ファイルごとに構成できます。プラットフォーム間で一貫した正しい動作を保証するために、

于 2010-07-08T13:36:27.390 に答える
0

ファイルにロックフラグとロック解除フラグを使用している場合でも、Javaアプリケーション内に排他ロックがあることを保証するだけです。

Windowsファイルの排他ロックを保証するためにWindows呼び出しを行うには、JNIまたは別のコンピューター言語を使用する必要があります。

WindowsのLockFile関数

WindowsのUnlockFile関数

于 2010-07-08T13:14:50.047 に答える