- 締切済み
スレッドでの画面表示中に、マウス処理が重くなる
画面クラス(class mytailf extends JFrame)と、ファイル読み込みクラス(class LogFilter extends Thread)があります。どちらも自作のクラスです。 ログファイルを読み込んで、画面に表示しているのですが、画面でのマウス操作が非常に重くなる場合があります。 質問1 画面クラス.ログ表示命令はどちらのスレッドで実行されるのでしょうか?ソースでは以下の部分です。 //ログを表示します。 myScreen.displayLog(strLine); 質問2 なにか改善策がありますでしょうか? なお、動作概要は以下のとおりです。 1.画面クラスを新規作成 2.画面クラスで、ファイル読み込みクラスを作成(引数は画面クラス)、Start()を実行 3.ファイル読み込みクラスで、ファイルから一行読み込み、画面クラス.ログ表示命令(引数は読み込んだ行)を呼び出す //-------------以下ソースの抜粋--------- // //画面制御系 // public class mytailf extends JFrame { //ログの読み込みクラス LogFilter myLogFilter = new LogFilter( this ); //条件に応じて、ログを振り分けます void displayLog(String strLine){ //ログを表示しているMDI子供窓に、ログを表示する処理 } // public static void main(String[] args) { new mytailf("MyTail_F").setVisible(true); } } // //ファイル読み込み系 // public class LogFilter extends Thread{ //ログ読み込み処理本体 public void run(){ while (ファイル読み込み中) { try { //* ファイルから一行読み込みます。 //* ファイルから行が読み込めている間、以下の処理を繰り返します。 while (ファイルから行が読み込めている間) { //ログを表示します。 myScreen.displayLog(strLine); //~他のスレッドに実行権を渡そう~// Thread.yield(); mySleepMs(100); lineCnt++; if(lineCnt >= 30){ mySleep(intWaitSec); lineCnt = 0; } } } catch (IOException e) { showStatus("ファイルの読み込みに失敗しました。"); System.out.println(e); return; } mySleep(intWaitSec); } } //コンストラクタ public LogFilter(mytailf argScreen){ super(); myScreen = argScreen; } //ログファイルを開く public void openLogFile(String strFileName){ //略 } //指定秒数待機 private void mySleep(int argSleepSec){ mySleepMs(argSleepSec * 1000); // X秒間停止 } //ミリ秒待機 private void mySleepMs(int argSleepSec){ try { Thread.sleep(argSleepSec); // Xミリ秒間停止 } catch (InterruptedException e) { System.out.println(e); } } }
- みんなの回答 (1)
- 専門家の回答
みんなの回答
- komi1341
- ベストアンサー率65% (25/38)
> 質問1 画面クラス.ログ表示命令はどちらのスレッドで実行されるのでしょうか? LogFilterクラスのスレッドです。少なくともそういうコードを書かれてますよね。 > 質問2 なにか改善策がありますでしょうか? 抜粋された部分を見る限りでは、1行読み込んではスリープ、という処理が重くなる原因になりそうです。ログの量やどれくらいの頻度でログファイルを読みに行くかなど、条件がいろいろありそうなので参考意見にしかなりませんが、 1.ファイルをまず全部メモリに読み込む。 2.それらの行を一気にmytailfクラスに渡す。 3.スリープするならその後。 という形に書き換えてはいかがでしょうか。
お礼
遅くなりましたがようやく原因が判明しましたのでご報告を。 読み込んだログが多くなればなるほど、 javax.swing.text.html.HTMLDocument.insertBeforeEnd(Element elem, String htmlText) が、長時間掛かるようになり、最悪10秒単位必要になることが判明しました。 #反応が悪くなる訳だわこりゃ^^;
補足
回答と改善策を有難うございます。 実行されるスレッドについては、理解しました。 ログは某オンラインゲームのログですので、サイズは最大メガバイト単位で、ゲームクライアントが書き出したログを、上記プログラムでリアルタイムで読み込んで居ます。(なので、追記されたログも、少し後に画面に出します)書き出し頻度は最大で1秒に数行くらいでしょうか。書かないときには数分間、一行も書かないのですが。 そのログを、行ごとに内容を調べて、別々のMDI窓に出しているので、ファイルを一気に読み込むわけにも行かず・・。 1行読み込んでは(100ms)スリープ、と、Thread.yield();という処理がないと、規定行数のログを読み込むまで、マウスが固まったので、入れたような記憶があります。 後日、Thread.yield();だけにして試して見ます。