final

まあなんかネットワークにアクセスするコードがあった。ネットワークアクセスは同期になってしまうので、待たなくちゃいけなくて、待ちたくないのでスレッドプールだったかを使う。

void accessNetwork() {
    if (handler == null) {
        handler = new requestHandler() {
            void processResponse(BufferedReader response) {
               // なんかネットワークから帰って来た返事をあれこれする
            }
        };
    }
    executer.execute(handler);
}

いろんなURLにアクセスしていろんなことをやるので、requestHandlerはなんか適当にアクセスする部分をやってくれるクラス。processResponseだけオーバーライドして使う。GCさせたくないので、メモリアロケーションは最低限におさえたい。なので一度生成したインスタンスはhandlerにキャッシュする。

まあ、なんとなく動いてた。

で、いろいろあって、ネットワークアクセスにかかってる時間をはかりたかったので、こんな感じで書き換えた。

void accessNetwork() {
    long t1 = System.currentMillisecond();
    if (handler == null) {
        handler = new requestHandler() {
            void processResponse(BufferedReader response) {
               // なんかネットワークから帰って来た返事をあれこれする
               Debug.print(System.currentMillisecond() - t1);
            }
        };
    }
    executer.execute(handler);
}

当然コンパイルできない。t1にfinalを付けてあげないと。

で、実行したら、なんかおそろしい時間がかかってることになってる。そんな馬鹿な。


これはrequestHandlerのインスタンスをキャッシュしてたのが原因。一回目のt1の値をずっと見てたらしい。なるほどねえ。

結局、t1をフィールドに出して解決。解決っていうか、えーと、まあ、他に方法思い付かんかったし。こんなことがあるんだなーって思った。