- 3.1. チャネル(Channel)
- 3.2. ファイルチャネル(FileChannel)
- 3.3. MappedByteBuffer
- 3.4. ロック
3.4. ロック
New I/O にはファイルのロック機能が追加されました。ファイルのロックとは、ファイルをあるプログラムで使用している間、ほかのプログラムからの読み書きを制限する目的で使用される仕組みです。ロックの概念はスレッドプログラミングの排他処理等においても使用されています。
スレッドプログラミングの排他制御と大きく異なるのは、このロックは複数の仮想マシンをまたいで有効である点です。synchronizedブロック等で使用されるオブジェクトのロックは異なる仮想マシン間で共有できませんが、このファイルロックは異なる仮想マシン上で実行されるプログラム間でも排他制御が実現できます。
New I/O のファイルロックには2種類あります。
種類 |
説明 |
共有ロック |
ほかのプログラムが排他ロックを獲得している間は共有ロックを獲得できません。 ほかのプログラムが共有ロックを獲得している間でも共有ロックは獲得できます。 |
排他ロック |
ほかのプログラムが共有ロックや排他ロックを獲得している間は排他ロックを獲得できません。 |
ファイルのロックを獲得するには、FileChannelクラスのlockメソッドまたはtryLockメソッドを使用します。
- FileLock lock()
- FileLock lock(long position, long size, boolean shared)
- FileLock tryLock()
- FileLock tryLock(long position, long size, boolean shared)
lockとtryLockの違いは、lockメソッドはロックを獲得するまでの間処理をブロックして待機するのに対して、tryLockはロックがただちに獲得できなかった場合にもすぐにメソッドを終了する点です。ほかのプログラムによりロックが獲得されているような場合に、そのロックが解放されるの待ちたい場合はlockメソッドを使用します。これらのメソッドは戻り値としてファイルロックを表すFileLockオブジェクトを返しますが、tryLockメソッドでロックが獲得できなかった場合はnullが返されます。
ファイルのロックはファイルの一部分に対しても定義することができます。lock/tryLockメソッドの引数position/sizeで、ロックの対象とする領域のファイル内での位置と大きさを指定します。領域が重複しない複数のロックはお互いに影響することはありません。
共有ロック・排他ロックの指定は引数sharedで指定します。共有ロックはtrue、排他ロックはfalseを使用します。なお、OSによっては共有ロックがサポートされていない場合があり、そのときは共有ロックを要求しても排他ロックが使用されます。獲得したロックが共有ロックか排他ロックかを調べるには、FileLockクラスのisSharedメソッドを使用します。
引数のないlock/tryLockメソッドは、ファイル全体を対象とする排他ロックを獲得しようとします。つまり、lock(0, Long.MAX_VALUE, false)/tryLock(0,Long.MAX_VALUE, false)と同等になります。
獲得したロックを解放するには、FileLockクラスのreleaseメソッドを呼び出します。
(実習課題3)
以下の仕様を満たすアプリケーションを作成してください。
- Long型のデータ1つを保持するファイルをカウンタとして扱うプログラム。ファイル名は固定で構わない。
- ファイルから数値を読み込み、10秒後にその値を+1した値をファイルに書き込んでプログラムを終了すること。書き込んだ値はコンソールにも出力すること。
- カウンタファイルが存在しなかった場合、値0が書き込まれたファイルを新規作成し直ちにプログラムを終了すること。
- Long型データの入出力にはLongBufferを利用すること。
- カウンタの増加を排他的に行うこと。異なる仮想マシン上で同時にこのプログラムが実行されても、プログラムを実行された回数だけ確実にカウンタ値が増加していること。