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をフィールドに出して解決。解決っていうか、えーと、まあ、他に方法思い付かんかったし。こんなことがあるんだなーって思った。