<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    如鵬網 大學生計算機學習社區

    CowNew開源團隊

    http://www.cownew.com 郵件請聯系 about521 at 163.com

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      363 隨筆 :: 2 文章 :: 808 評論 :: 0 Trackbacks

    作者楊中科是CowNew開源團隊JDBMonitor項目組的開發人員。
    CowNew開源團隊網站 http://www.cownew.com
    論壇 http://www.cownew.com/newpeng/
    轉載請注明此版權信息

    數據庫監控、日志工具JDBMonitor在介紹文檔中說到“JDBMonitor另起一個線程來記錄SQL,所以它不會對程序運行速度有任何影響?!?,那么它是如何做到的呢?
    JDBMonitor采用“生產者-消費者模型”完成此功能。學過操作系統原理的朋友對“生產者-消費者模型”一定不陌生,它是和“哲學家進餐問題”等相提并論的經典模型。
    JDBMonitor的主線程做為“生產者”,產生“日志信息”這個產品,另起一個線程做為消費者,這個消費者負責“消費”日志信息,并把日志信息派發給所有的監聽者,這樣日志的產生和消費是獨立的,所以無論日志的派發有多慢,都沒有關系,都不會影響到主線程的運行速度。下面讓我們深入研究一下:
    (注:JDBMonitor的二進制jar包和源代碼都可以從 http://www.cownew.com 下載得到。)
    打開com.cownew.JDBMonitor.common.DBLogger。JDBMonitor每次截獲到一條sql語句,都會調用logSQL方法,并把sql語句的信息對象傳過來,這樣我們就可以把logSQL方法當成生產者,logsql把消息放到channel中。LogConsumer是一個實現了Runnable接口的類,它就是日志的消費者,并且是運行于另一個線程的,它負責實時檢測channel,只要channel中有東西,他就從channel取出日志對象,然后發送給各個監聽器。
    startConsumer中
    for (;;)
    {
    ? SQLInfo info = (SQLInfo) channel.take();
    ? for (int i = 0, n = dbListeners.length; i < n; i++)
    ? {
    ??? dbListeners[i].logSql(info);
    ? }
    }
    就是在實時檢測channel中的產品。
    channel是一個阻塞通道BlockedChannel的實例,這個阻塞通道主要提供兩個方法offer,take,offer方法向通道中放入產品,take從通道中取產品,當通道中沒有產品的時候,take方法將會阻塞,直到有產品為止。BlockedChannel是靠java的wait-notify機制實現的,原理非常簡單,有興趣的朋友看一下其實現代碼就可以。
    值得注意的是,LogConsumer是一個后臺線程,因為如果LogConsumer不是后臺線程,那么由于LogConsumer一直在無限循環里執行,所以程序就不能正常終止。而設置為后臺線程后,在其他工作線程停止后,此線程就會自動終止。關于“后臺線程”的知識,可以查看相關資料。
    但是采用后臺線程以后,又有另一個問題出現了,在主線程停止后,有可能產品通道channel中還有沒有發送完的日志信息,這樣就會造成漏記日志信息。
    Runtime 類有一個addShutDownHook方法,可以調用此方法向JVM注冊一個監聽器,這個監聽器必須實現Thread接口,在JVM停止之前,這個監聽器將會被運行,這樣我們就可以在JVM停止之前做一些事情了。
    JDBMonitor就是用addShutDownHook解決此問題的。見DBLogger的靜態初始化塊:

    Runtime.getRuntime().addShutdownHook(new Thread(){
    ? public void run()
    ? {
    ??? //once JVM will shutDown,this hook will pause the shutingdown
    ??? //until all the SQLInfo be dispatched
    ??? while (!channel.isEmpty())
    ??? {
    ????? try
    ????? {
    ??????? Thread.sleep(SHUTDOWNSLEEPMSECOND);
    ????? } catch (Exception e)
    ????? {
    ??????? throw CommonUtils.toRuntimeException(e);
    ????? }
    ??? }
    ??? ...
    ?? }
    });?

    在JVM停止之前會首先檢測產品通道中有沒有產品,如果還有,則會一直等到產品被消費完后再終止。

    ?while (!channel.isEmpty())
    ??? {
    ????? try
    ????? {
    ??????? Thread.sleep(SHUTDOWNSLEEPMSECOND);
    ????? } catch (Exception e)
    ????? {
    ??????? throw CommonUtils.toRuntimeException(e);
    ????? }
    ??? }

    posted on 2006-06-02 23:46 CowNew開源團隊 閱讀(946) 評論(0)  編輯  收藏

    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 人人狠狠综合久久亚洲高清| 国产亚洲综合色就色| 亚洲国产精品久久网午夜| 日韩插啊免费视频在线观看| 亚洲开心婷婷中文字幕| a一级毛片免费高清在线| 在线观看亚洲天天一三视| 国产免费高清69式视频在线观看| 亚洲AV无码不卡在线观看下载| 色婷婷亚洲一区二区三区| 免费观看国产精品| 偷自拍亚洲视频在线观看| 亚洲日本一区二区一本一道| 亚洲一区二区三区免费| 亚洲成AV人在线观看天堂无码| 一区二区三区无码视频免费福利| 亚洲AV午夜成人片| 日韩欧毛片免费视频| 亚洲av永久无码精品网址| 免费不卡中文字幕在线| 中国videos性高清免费| 亚洲韩国在线一卡二卡| 国产成人亚洲午夜电影| 亚洲精品国自产拍在线观看 | 中文文字幕文字幕亚洲色| 成人无码区免费A片视频WWW| 国产亚洲精品AAAA片APP| 亚洲午夜久久久影院| 2021久久精品免费观看| 午夜亚洲WWW湿好爽 | 四虎www免费人成| 亚洲日韩在线观看免费视频| 亚洲网站视频在线观看| 亚洲大码熟女在线观看| 亚洲情a成黄在线观看| 久久综合九色综合97免费下载| 亚洲午夜成激人情在线影院| 免费看国产精品麻豆| 久久精品免费视频观看| 麻豆亚洲AV成人无码久久精品| 亚洲国产三级在线观看|