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

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

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

    如鵬網(wǎng) 大學(xué)生計(jì)算機(jī)學(xué)習(xí)社區(qū)

    CowNew開源團(tuán)隊(duì)

    http://www.cownew.com 郵件請聯(lián)系 about521 at 163.com

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

    作者楊中科是CowNew開源團(tuán)隊(duì)JDBMonitor項(xiàng)目組的開發(fā)人員。
    CowNew開源團(tuán)隊(duì)網(wǎng)站 http://www.cownew.com
    論壇 http://www.cownew.com/newpeng/
    轉(zhuǎn)載請注明此版權(quán)信息

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

    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停止之前會首先檢測產(chǎn)品通道中有沒有產(chǎn)品,如果還有,則會一直等到產(chǎn)品被消費(fèi)完后再終止。

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

    posted on 2006-06-02 23:46 CowNew開源團(tuán)隊(duì) 閱讀(942) 評論(0)  編輯  收藏

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


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 日韩一区二区a片免费观看 | 亚洲欧洲国产综合| 韩国免费A级毛片久久| 亚洲国产精品成人| 成人免费网站久久久| 亚洲av无码国产精品色在线看不卡 | a级毛片毛片免费观看久潮| 久久亚洲欧洲国产综合| 女人裸身j部免费视频无遮挡| 最近免费中文字幕视频高清在线看| 亚洲高清有码中文字| 日日操夜夜操免费视频| 国产精品亚洲二区在线| 夜色阁亚洲一区二区三区| 一级毛片免费播放试看60分钟| 中文字幕精品亚洲无线码一区| 久久精品无码免费不卡| 亚洲av无码不卡| 最近免费视频中文字幕大全| 亚洲av乱码一区二区三区香蕉| 久久不见久久见免费影院| 色偷偷尼玛图亚洲综合| 国产成人精品久久亚洲| 久99久精品免费视频热77| 亚洲一区二区三区四区视频| 免费看AV毛片一区二区三区| 国产成人亚洲精品电影| 亚洲色成人WWW永久网站| av无码久久久久不卡免费网站| 亚洲精品无码aⅴ中文字幕蜜桃| 亚洲 小说区 图片区 都市| 久久一区二区三区免费| 亚洲精品综合久久中文字幕| 免费黄色毛片视频| 中文字幕无线码中文字幕免费| 久久精品国产亚洲AV麻豆网站| 啦啦啦高清视频在线观看免费| 成年大片免费视频播放一级| 九月丁香婷婷亚洲综合色| 男人的好免费观看在线视频| 国产成人精品免费大全|