無料で使えるシステムトレードフレームワーク「Jiji」 をリリースしました!

・OANDA Trade APIを利用した、オープンソースのシステムトレードフレームワークです。
・自分だけの取引アルゴリズムで、誰でも、いますぐ、かんたんに、自動取引を開始できます。

ReentrantLock

ReentrantLock は synchronized を使用したロックです。1.5から追加されました。

基本的な使い方:

final Lock lock = new ReentrantLock();
try {
    lock.lock(); // ロックする。

    // 処理

} finally {
    lock.unlock(); // ロックを解放。
}

もうちょっと長いサンプル:

class WithLock implements Runnable {

    /**ロック*/
    final Lock lock;
    /**ロックしてから実行する処理*/
    final Runnable procedure;

    /**
     * コンストラクタ
     * @param lock ロック
     * @param procedure ロックしてから実行する処理
     */
    WithLock ( Lock lock, Runnable procedure ) {
        this.lock = lock;
        this.procedure = procedure;
    }

    public void run () {
        try {
            lock.lock(); // ロックする。
            procedure.run();
        } finally {
            lock.unlock(); // ロックを解放。
        }
    }
}

class Say implements Runnable {

    /**名前*/
    final  String name;

    /**
     * コンストラクタ
     * @param name 名前
     */
    Say ( String name ) {
        this.name = name;
    }

    public void run () {
        try {
            System.out.println( name );
            Thread.sleep( 100 );
            System.out.println( name + "!" );
            Thread.sleep( 100 );
            System.out.println( name + "!!" );
        } catch ( InterruptedException e ) {
            // 誰も止めない。
        }
    }
}

final Lock lock = new ReentrantLock();
String[] names = new String[]{ "shiro", "kuro", "tora", "mii" };

// ロックしない。// バラバラになる。
for ( int i = 0; i < names.length; i++  ) {
    Runnable run = new Say( names[i] );
    new Thread( run ).start();
}

Thread.sleep( 1000 );
System.out.println( "---" );

// ロックする。// 整列する。
for ( int i = 0; i < names.length; i++  ) {
    Runnable run = new WithLock ( lock, new Say( names[i] ) );
    new Thread( run ).start();
}

実行すると、ロックした場合は名前がバラバラにならず、排他制御ができているのがわかります。

出力:

shiro
kuro
tora
mii
mii!
tora!
kuro!
shiro!
mii!!
shiro!!
kuro!!
tora!!
    • -
shiro shiro! shiro!! kuro kuro! kuro!! tora tora! tora!! mii mii! mii!!

lockするスレッドとunlockするスレッドは同じでなければなりません。
別スレッドでunlockを実行するとエラーになります。

final Lock lock = new ReentrantLock();
try {
    lock.lock();

    // 処理

} finally {
    // 別スレッドでは解放できない。
    new Thread() {
        public void run() {
            lock.unlock(); // java.lang.IllegalMonitorStateExceptionが発生。
        }
    }.start();
}