Javaに関する様々な情報をご紹介します。

Javaに関する様々な情報をご紹介します。
評価

0

ExecutorServiceの終わらせ方

はじめまして。

Strutsを使ってアプリ起動時に5秒毎に外部サイトより値を取得しメモリにキャッシュするプログラムを作っています。

以下がそーすですが。
スレッドだけにメモリヒープが気になっています。
eclipseのメモリの表示で起動後ずっと見ていると確かに徐々にメモリが上がっていってしまいます。

スレッドの生成・破棄のプロセスがはっきりしていれば良いのですが、こちらのソースで問題ないでしょうか?

「ExecutorService.shutdown();」しても下記Counterのスレッドは周り続けているのですが・・。
仕様的には良いのですが、本来下記destroy()内に入れるべきかとも思うのですが。。

よろしくお願いします。

@@@@@@@@@@@@@@@@@
package servlet;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.servlet.ServletException;

import org.apache.jcs.JCS;
import org.apache.struts.action.ActionServlet;
import org.apache.struts.action.PlugIn;
import org.apache.struts.config.ModuleConfig;

import app.util.TradeUtil;

public class RealTimePlugin implements PlugIn {

 private ExecutorService ex = null;

 public void init(ActionServlet servlet, ModuleConfig config)
   throws ServletException {
  this.start();
 }

 public void destroy() {
 }

 public void start() {
  // Webアプリケーションの開始処理
  System.out.println("-->RealTimePlugin Start..");

  ex = Executors.newFixedThreadPool(1);
  ex.submit(new Counter());

  // Webアプリケーションの開始処理
  System.out.println("-->RealTimePlugin End..");
  ex.shutdown();
 }

 class Counter implements Runnable {
  private TradeUtil tu = new TradeUtil();
  private boolean flg = false;

  // runメソッドをオーバーライド
  public void run() {
   while (true) {
    try {
     if (!flg)
      vvv();
     Thread.sleep(5000);
    } catch (InterruptedException e) {

    }
   }
  }

  // 処理
  public void vvv() {
   flg = true;
   BufferedReader reader = null;
   HttpURLConnection con = null;
   InputStreamReader is = null;
   try {
    //HTTPから値の取得
    URL url = new URL("http://yahoo.co.jp");
    con = (HttpURLConnection) url.openConnection();
    con.setRequestMethod("GET");
    con.setInstanceFollowRedirects(false);
    con.setRequestProperty("Accept-Language", "ja;q=0.7,en;q=0.3");
    con.connect();

    is = new InputStreamReader(con.getInputStream());
    reader = new BufferedReader(is);
    while (true) {
     String line = reader.readLine();
     if (line == null) {
      break;
     }
     JCS cache = JCS.getInstance("default");
     if (cache != null && line != null) {
      cache.put("rate", line.trim());
     } else {
      System.out.println("更新失敗。");
     }
     System.out.println("@" + line);
    }
   } catch (Exception e) {
    System.out.println("更新失敗。");
    e.printStackTrace();
   } finally {
    try {
     is.close();
    } catch (Exception e) {
    }
    try {
     reader.close();
    } catch (Exception e) {
    }
    try {
     con.disconnect();
    } catch (Exception e) {
    }
    flg = false;
   }
  }
 }
}

3

回答

9000

閲覧

3件の回答

評価

0

ほんの少し下にヒントがあるじゃないか。

http://www.javaroad.jp/bbs/answer.jsp?q_id=20100723033008823

評価

0

ありがとうございます。

そちらの回答を見てExecutorServiceを知って実装したのですが、スレッドのプロセスが本当に殺されているか分からない状態です。

例えば、下記のソースのこの部分を繋げてますが、
  ex = Executors.newFixedThreadPool(1);
  ex.submit(new Counter());
  ex.shutdown();
shutdown()したらThread(下記Counterクラス)も止まると思っていたのですが、延々うごいています。

本来はWebServerシャットダウン時にこれらのプロセスを殺してくれているのであれば、問題は無いのですが(スレッド終了は明示的に書かずに良い)。。

実は他BBSで質問してしまっていますが、普通のThreadを実装していました、開発環境(WinXP)では正常に動作するのですが、Linuxに移すと「This is very likely to create a memory leak」とエラー出力され、このスレッドが実行されない問題に当たりました。

よろしくお願いします。

評価

0

解決しました。

一行づつ確認したら、別の原因で異常終了している為でした。
Exception.printstacktrace()をかけてたので安心してたんですが、何も出力されず原因を掴めませんでした。てっきりメモリ割り当てに起因したエラーと思い込んでしまいました。表示したソースでは割愛しました、Bigdecimalで変換をかけていました(数値であるべき所が文字列)。

でも何で異常終了するのに例外を吐かないんでしょう。。

質問から6ヶ月以上経過しているので、回答を書き込むことはできません。