Index: [Article Count Order] [Thread]

Date:  Wed, 27 Sep 2000 20:06:05 +0900
From:  tetsuya@....jp
Subject:  [XP-jp:00965] ファイルロックユーティリティ
To:  extremeprogramming-jp@....jp (extremeprogramming-jp ML)
Message-Id:  <97BA340C0480D411BDA800062939A1890607B6@....jp>
Posted:  Wed, 27 Sep 2000 20:04:12 +0900
X-Mail-Count: 00965

栗原です。

自分で、ファイルのロックが必要と懸念点をあげているならば、
その懸念を払拭してから進むべきですよね。
# 不明点を明らかにしないとタスクを見積もれませんから。

で、並行処理時のファイルロックユーティリティを作ってみました。

/*
 * $Id$
 */
package XP.jp.co.esm.wiki.extremedomo.util;

public class MutexException extends Exception {
    public MutexException() {
        super();
    }
    public MutexException(String s) {
        super(s);
    }
}

/*
 * $Id$
 */
package XP.jp.co.esm.wiki.extremedomo.util;

public class AttemptTimeOutException extends MutexException {
}

/*
 * $Id$
 */
package XP.jp.co.esm.wiki.extremedomo.util;

import java.io.*;

public class Mutex {
    public Mutex(String nameOfLockFile) {
        lockFile = new File(nameOfLockFile);
    }
    public void attempt(long milliSec)
        throws MutexException {

        try {
            if (lockFile.createNewFile())
                return;
            else if (milliSec <= 0)
                throw new AttemptTimeOutException();
            else {
                long startTime = System.currentTimeMillis();
                long retryTime = 0;

                while (true) {
                    Thread.currentThread().sleep(intervalTime);
                    if (lockFile.createNewFile())
                        return;
                    else {
                        long nowTime = System.currentTimeMillis();
                        retryTime += nowTime - startTime;
                        if (milliSec < retryTime)
                            throw new AttemptTimeOutException();
                    }
                }
            }
        } catch (IOException e) {
            throw new MutexException(e.toString());
        } catch (InterruptedException e) {
            notify();
            throw new MutexException(e.toString());
        }
    }
    public void release() {
        lockFile.delete();
    }

    private final File lockFile;
    private final long intervalTime = 50;
}

パッケージutilを作らせてもらいました。
Mutexという名前はどうかと思いますが、Win32環境で、こんなAPIが
あったなと。
いわゆるマルチスレッドでないので、平鍋さんが提示して下さったよう
に、File.createNewFileメソッドによるファイルでのロックを使用して
います。

コンストラクタには、ロックファイルの名前を指定します。
# この名前をどこからもってくるのかは???

attemptメソッドで、ロックファイルの作成を試みます。
引数には、ロックファイル作成までの最大待ち時間をミリ秒単位で指定
します。
もしも待ち時間を過ぎても、別プロセスによって作成されたロックファ
イルが存在しているときは、例外AttemptTimeOutExceptionが投げられ、
ロックが失敗します。

ロックの開放はreleaseメソッドで行います。

ロック取得のためのリトライ間隔は、、、とりあえず暫定的に決め打ち
してます。(intervalTime)

このクラスの使用方法ですが、以下のようなものになります。

    Mutex mutex = new Mutex("lock");
    try {
        mutex.attempt(100000);

        try {
            // 原子的に行われる処理
        } finally {
            mutex.release();
        }
    } catch (MutexException e) {
        // ロック獲得に失敗!
    }

現在プロセスで作成したロックファイルは確実にリリースされるようにし
ます。

で、肝心のテストケースですが、自分なりにテストして、正しく動作しそ
うだ、というのは確認しているのですが、JUnitなどでどのようにテスト
していいのかが検討つきません。
並行処理のテストの良いアイデアは何かありませんでしょうか?
アドバイスお願いします、識者の方々。

---
Tetsuya Kurihara
tetsuya@....jp