前提・実現したいこと
TomcatにJavaで作ったwebアプリをデプロイし公開する。
そのwebアプリをリリースして以降、ある処理を一定間隔で実行し続けたい。
そのwebアプリをアンデプロイした際は定期処理を終了したい。
そのwebアプリを再デプロイした際は定期処理を初期化し、再度実行を開始したい。
発生している問題
・Tomcatからwebアプリをアンデプロイした際にその処理が止まらない
・Tomcatに同じwebアプリを再デプロイした際にスレッドが重複していってしまう。
該当のソースコード
webアプリをデプロイした際に初期処理をするクラス
Java
1public class InitialServlet extends HttpServlet { 2 // 初期処理を記述して下さい。 3 public void init() throws ServletException { 4 ScheduleManager schedule = ScheduleManager.getInstance(); 5 schedule.start(); 6 }
定期処理を開始するクラス
Java
1public class ScheduleManager extends Thread { 2 3 private static ScheduleManager instance = new ScheduleManager(); 4 private static Timer timer = new Timer(); 5 6 private ScheduleManager() { 7 } 8 9 @Override 10 public synchronized void run() { 11 if (timer != null) { 12 // 既にtimerがあれば停止する 13 timer.cancel(); 14 System.out.println("stop run"); 15 } 16 // timerの開始 17 System.out.println("start run"); 18 timer = new Timer(); 19 timer.schedule(Schedule.getInstance(), 0, 2000); 20 } 21 22 public static ScheduleManager getInstance() { 23 return instance; 24 } 25}
定期処理の実装
Java
1class Schedule extends TimerTask { 2 3 private static Schedule instance = new Schedule(); 4 private Schedule() { 5 } 6 int testCount = 0; 7 8 @Override 9 public void run() { 10 System.out.println(testCount + "回目"); 11 testCount++; 12 } 13 14 public static Schedule getInstance() { 15 return instance; 16 } 17}
試したこと
ScheduleManagerクラスやScheduleクラスをシングルトンクラスにしてみたりしましたが、実行結果が以下のようになってしまいます。
webアプリを再配置する毎に処理が重複されて定期実行されてしまいます。
なお、Tomcatを再起動すればまた"1回目"から始まりますが、運用上Tomcatを止める事は出来ません。
113回目 63回目 91回目 114回目 64回目 92回目 115回目 65回目 93回目 116回目 66回目 94回目
望んでいる実行結果
1回目 2回目 3回目 4回目←ここでwebアプリを再配置したとすると stop run start run 1回目 2回目 3回目 4回目
FW/ツールのバージョンなど
apache-tomcat-7.0.78
補足
お恥ずかしいですが独学で学んでいるため、笑ってしまうような実装があるかと思います。
出来れば今回の質問の本題以外のご指摘もありましたら是非宜しくお願いします。
また、質問内容に不備がありましたら追記致します。
お手数お掛け致しますが助言を宜しくお願いします。
内容から見るとデプロイされている間というのはそのデプロイ中(初期化処理中)ではなくリリース完了後以降(初期化終了後)と読み替えていいですか?
仰る通りです。質問内容を訂正します。
またさらに内容見ると、どちらかというと定期処理をデプロイ時に初期化したいと読み取れるのですが、あってますか?
仰る通りです。質問内容を訂正します。
以下のようなリスナーを追加したところ、もしかしたらうまく動いているかもしれません。
その他の解決方法やご指摘等ありましたら宜しくお願い致します。
Java
1public class InitializationListener implements ServletContextListener { 2 3 public void contextInitialized(ServletContextEvent event) { 4 // 起動を検知 5 System.out.println("/////////////////////////////////////////////////////////////////"); 6 System.out.println("Initialized"); 7 System.out.println("/////////////////////////////////////////////////////////////////"); 8 ScheduleOutput.getInstance().startTimer(); 9 } 10 11 @Override 12 public void contextDestroyed(ServletContextEvent event) { 13 //終了を検知 14 System.out.println("/////////////////////////////////////////////////////////////////"); 15 System.out.println("Destroyed"); 16 System.out.println("/////////////////////////////////////////////////////////////////"); 17 ScheduleOutput.getInstance().stopTimer(); 18 }
回答3件
あなたの回答
tips
プレビュー