今日の役に立たない一言 - Today’s Trifle! -

古い記事ではさまざまなテーマを書いていますが、2007年以降はプログラミング関連の話がほとんどです。

あるメソッドを別スレッドで動作させるリファクタリング

もともとはシーケンシャルに動作していたメソッドの実装を変更するとき、場合によってはもともと予定していたよりも時間がかかる処理を実行しなければならないことがある。処理の内容が、シーケンシャルな処理に影響を及ぼさない(例えば他のシステムに処理をリクエストして結果を記録するだけなど)ならば、単純に別のスレッドで実行すればよい。
もとのコードが以下とする。

    void someMethod() {
        // 時間がかかる処理
    }

これを別スレッドで動作させるようにリファクタリングする。someMethod() のメソッドシグネチャを変更しないのがポイント。
まずは someMethod() の名前を slowProc() に変更する。次に someMethod() を作成。someMethod() の中では SlowProcThread を起動する。SlowProcThread を作成する。SlowProcThread の run() で slowProc() を呼び出す。

    void someMethod() {
        SlowProcThread t = new SlowProcThread();
        t.start();
    }

    void slowProc() {
        // 時間がかかる処理
        // もとは someMethod() の内容そのまま
    }

    class SlowProcThread extends Thread {
        public void run() {
            slowProc();
        }
    }

もとの someMeshod() の内容が atomic に作られているとするならば、それはそのままメソッドとして残した方が良い。
自分でも SlowProcThread の run() 内に someMethod() の内容を丸ごとコピーするようなリファクタリングをしそうになるけど、そうするとスコープが変化したりして期待通りに動作しなくなることがある。