java daemon thread的實踐應用

最近項目開發中遇到了一些不明的尷尬狀況,程序運行很長時間都不退出,致使服務崩潰。通過分析,可能會是sql查詢永久性等待(與ORM有關)、maven打包前執行maven clean命令,也多是尚未想到的緣由。。。java

爲了解決這個大bug,至少在緣由明瞭以前暫時應付。我寫了一個監控程序運行時間並強制退出的功能,多少安心了。sql

附scala代碼,java天然也是大同小異的。
maven

import org.joda.time.DateTime
import core.traits.LogTrait
object ExitKit extends LogTrait {
  val secondsNum = 1     //s
  val minuteNum = 60     //s
  val hourNum = 3600      //s
  val dayNum = 3600 * 24     //s
  /**
   * ms爲單位
   */
  val sleepTime = 10000
  /**
   * 程序異常退出時的code
   */
  val exitCode = 3
  def monitorExit() {
    val excuteTime = sys.props.get("sys.maxExcuteTime")
    if (excuteTime != None) {
      logger.info("進行運行時間控制")
      val timeType = sys.props.getOrElse("sys.timeType", "s").toLowerCase
      var timeLast = excuteTime.get.toInt
      logger.info("sys.timeType:{}", timeType)
      if (timeType == "s") {}
      else if (timeType == "m") {
        timeLast = timeLast * minuteNum
      }
      else if (timeType == "h") {
        timeLast = timeLast * hourNum
      }
      else if (timeType == "d") {
        timeLast = timeLast * dayNum
      }
      logger.info("sys.maxExcuteTime:" + timeLast + " s")
      /**
       * 一個守護線程,若是程序長時間不退出,能夠經過它來使程序強行退出,退出時code爲 exitCode=3
       */
      val daemonThread = new Thread(new Runnable {
        def run() {
          val start = System.currentTimeMillis()
          var end = start
          while (true) {
            end = System.currentTimeMillis()
            logger.info("end-start:" + (end - start) / 1000 + " s")
            /**
             * 其餘地方也能夠控制線程是否退出,經過設置sys.othersShut爲true
             */
            val othersShut = sys.props.getOrElse("sys.othersShut", "false")
            if (othersShut == "true")
              return
            if ((end - start) / 1000 > timeLast) {
              try {
                logger.info("System.exit(3),緣由:(end - start) / 1000 > " + timeLast.toString + " --- start:{},end:{}",
                  new DateTime(start).toString("yyyy-MM-dd HH:mm:ss"), new DateTime(end).toString("yyyy-MM-dd HH:mm:ss"))
              } catch {
                case t: Throwable => logger.info("System.exit(3),緣由:(end - start) / 1000 > " + timeLast.toString)
              }
              System.exit(exitCode)
            }
            try {
              Thread.sleep(sleepTime)
              logger.debug("--- monitorExit 休息{}秒 ---", sleepTime.toString)
            } catch {
              case t: Throwable =>
            }
          }
        }
      })
      daemonThread.setDaemon(true)
      println("--thread --- isDaemon? :" + daemonThread.isDaemon)
      daemonThread.start()
    } else {
      logger.info("進行運行時間控制")
    }
  }
}

功能也不是多麼厲害,主要涉及了Daemon Thread的特性,解決其餘線程在規定時間內已經所有退出時,程序天然也應該再也不監控運行時間了,應該退出的問題。
線程

本文出自 「沐浴心情」 博客,請務必保留此出處http://lj3331.blog.51cto.com/5679179/1250285scala

相關文章
相關標籤/搜索