FileChannelの&のRandomAccessFileは動作していないようです
質問
それを置くためには、単純な:バックエンドとして使用していますsqlitejdbcスイングアプリ。現在では、同じデータベースファイルで作業複数のインスタンスを起動何ら問題はありません。そして、そこにする必要があります。 ファイルがロックされている(アプリが起動している間、それを削除することはできません)ので、チェックは簡単でなければなりません。判明していない。
File f = new File("/path/to/file/db.sqlite");
FileChannel channel = new RandomAccessFile(f, "rw").getChannel();
System.out.println(channel.isOpen());
System.out.println(channel.tryLock());
で結果
true
sun.nio.ch.FileLockImpl[0:9223372036854775807 exclusive valid]
アプリを実行しているかどうかは関係ありません。私はポイント足りませんか? TIAます。
解決
FileLocksはJVMではなく、個々のスレッドに排他的です。あなたはSwingのアプリと同じプロセス内でそのコードを実行した場合、それはJVMによって共有されているので、だから、あなたがロックを取得します。
あなたのスイングのアプリが実行されていない場合、あなたはそれがうまくあり得るだろうように、、他のプロセスがロックを競合されません。
他のヒント
ファイル・システム・レベルのロックは、他のアプリケーションと対話します。あなたはのFileChannelからこれらのいずれかを取得します。ですから、ファイルを行いますあなたの例のコードでは何をすべきかの例viのために、別のプロセスにロックされているようです。
しかし、JVM内の他のJavaスレッドやプロセスは、ロックは表示されません。キーセンテンスの「ファイルロックはJava仮想マシン全体を代表して開催されている。彼らは、同じ仮想マシン内の複数スレッドによるファイルへのアクセスを制御するには適していません。」はのあなたが表示されませんロック、ので、あなたのアプリケーションと同じJVM内からsqlitejdbcを実行しています。
そこで問題は、あなたは(あなたがロックを取得コードを制御しないと仮定して)あなたのJVMがすでにファイルのロックを取得しているかどうかをどのように見ますか?私はこのコードで、たとえば、しようとすると、ファイルの異なるサブセットの排他的ロックを獲得されなければならない1つの提案ます:
fc.tryLock(0L, 1L, false)
ロックがすでに存在する場合、あなたはOverlappingFileLockExceptionを取得する必要があります。これは少しハックですが、動作する可能性があります。
あなたは少し実験を行うことができますか?
:このプログラム(スリープとちょうどあなたのコード)の2つのコピーを実行しますpublic class Main {
public static void main(String [] args) throws Exception {
File f = new File("/path/to/file/db.sqlite");
FileChannel channel = new RandomAccessFile(f, "rw").getChannel();
System.out.println(channel.isOpen());
System.out.println(channel.tryLock());
Thread.sleep(60000);
}
}
これはあなたのtryLock()が使用しているOS /ドライブ/ JVM上で動作していないことを知っているロックしない場合。これがロックしない場合は、何か他のものは、あなたのロジックが間違っています。私たちは、コメントに結果を教えてくださいます。