• 締切済み

スレッドでの画面表示中に、マウス処理が重くなる

画面クラス(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);     }   } }

みんなの回答

  • komi1341
  • ベストアンサー率65% (25/38)
回答No.1

> 質問1 画面クラス.ログ表示命令はどちらのスレッドで実行されるのでしょうか? LogFilterクラスのスレッドです。少なくともそういうコードを書かれてますよね。 > 質問2 なにか改善策がありますでしょうか? 抜粋された部分を見る限りでは、1行読み込んではスリープ、という処理が重くなる原因になりそうです。ログの量やどれくらいの頻度でログファイルを読みに行くかなど、条件がいろいろありそうなので参考意見にしかなりませんが、 1.ファイルをまず全部メモリに読み込む。 2.それらの行を一気にmytailfクラスに渡す。 3.スリープするならその後。 という形に書き換えてはいかがでしょうか。

osu_neko09
質問者

お礼

遅くなりましたがようやく原因が判明しましたのでご報告を。 読み込んだログが多くなればなるほど、 javax.swing.text.html.HTMLDocument.insertBeforeEnd(Element elem, String htmlText) が、長時間掛かるようになり、最悪10秒単位必要になることが判明しました。 #反応が悪くなる訳だわこりゃ^^;

osu_neko09
質問者

補足

回答と改善策を有難うございます。 実行されるスレッドについては、理解しました。 ログは某オンラインゲームのログですので、サイズは最大メガバイト単位で、ゲームクライアントが書き出したログを、上記プログラムでリアルタイムで読み込んで居ます。(なので、追記されたログも、少し後に画面に出します)書き出し頻度は最大で1秒に数行くらいでしょうか。書かないときには数分間、一行も書かないのですが。 そのログを、行ごとに内容を調べて、別々のMDI窓に出しているので、ファイルを一気に読み込むわけにも行かず・・。 1行読み込んでは(100ms)スリープ、と、Thread.yield();という処理がないと、規定行数のログを読み込むまで、マウスが固まったので、入れたような記憶があります。 後日、Thread.yield();だけにして試して見ます。

関連するQ&A