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

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

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


    竟 然64個annotation,沒有分類,放在同一個package下,同一個package(javax.persistance)還有其他java文 件,共有88個java文件。不看內容本身,單從表面,都覺得這是混亂不堪的事情。這是那個豬頭的杰作?glassfish上下載的源碼中,這些java 文件似乎都沒有author,估計也不好意思把名字放出來見人吧!

    ------

    覺得對象關系存儲方面一直沒有突破,也沒有好的產品出來,其中一個原因,就是從沒有過優秀的工程師投身過這個領域。關系數據庫為什么能夠一直堅守領地,成為絕大多數商業應用的基石,其中一個原因就是有過大量的精英投身于此,包括兩個圖靈獎獲得者。

    關 系數據庫,為了描述關系,創造一門SQL語言,將關系一些操作,例如投影(select)、選擇(where)、分組(group by)等等,抽象得形象易懂,功能強大。對于數據的操作,SQL語言是最強大,也是最方便的,也是最易于使用的。一些非程序員的IT從業人員,非計算機專 業的人員都能夠熟練掌握SQL。

    OO和Relational都是偉大的技術,從計算機最高榮譽獎可以看出這兩個技術的偉大。OO的圖靈獎獲得者是三個,Relational的圖靈獎獲得者是兩個。

    面向對象技術自1967年simula引進以來,所想披靡,93年-98年從C++開始流行,然后到Java,成為主流編程技術。Relational沒有OO那么輝煌,但是在數據存儲方面的地位固如磐石,長期占據絕對的地位。

    曾 經OO技術涉足于數據存儲領域,但終究沒有成功。面向對象數據庫的變現總是差強人意,面向對象的方式操作數據,總是不如使用關系那么方便,那么靈活,那么 易于使用,那么好的性能。于是人們在數據存儲和處理方面,不在青睞面向對象技術,而是仍然使用關系方式,使用SQL語言,使用關系運算操作數據。面向對象 數據庫成了曇花一現的東西,并且可能永遠都不會再流行了。

    OO成了主流編程技術,Relational占據了絕對的數據存儲地位,這兩大技術需要交互,需要橋接,這需要OR-Mapping。Relational雖然好,但我們也要與時俱進,所以也需要OR-Mapping。

    但 是,做OR-Mapping時,不積極吸取relational方式對數據處理的靈活性、方便性、簡單性,而只強調Relational和對象之間的的 Mapping,試圖以面向對象的方式操作數據,這是錯誤的方向。以前的EJB、現在Hibernate、JPA都犯了同樣的錯誤,試圖以更面向對象的方 式操作數據,從而導致復雜混亂的模型,這也是JPA的現狀吧。例如user.getGroup(),目前的ORM試圖以純OO的方式操作數據,所引起的 LazyLoad、n+1等問題,使得事情變得復雜而且混亂不堪。

    一些開發人員,去學習Hibernate,不學習SQL,有人提倡,只需要了解面向對象編程技術,不需要了解關系技術,亦屬于本末倒置。需求人員都會用的SQL語言,對數據操作最方便最簡單最強大的SQL語言,竟然成了令人生畏的紙老虎,可笑啊。

    -------------

    以下是過去的一些業界浮躁不理智:

    1、面向對象數據庫。曾被熱衷而吹捧,面向對象數據庫的變現總是差強人意,面向對象的方式操作數據,總是不如使用關系那么方便,那么靈活,那么易于使用,那么好的性能。于是人們在數據存儲和處 理方面,不在青睞面向對象技術,而是仍然使用關系方式,使用SQL語言,使用關系運算操作數據。面向對象數據庫成了曇花一現的東西,并且可能永遠都不會再 流行了。

    2、 JDO投票鬧劇。2004-2005年,JDO的JSR在JCP投票被否決的,無聊者在Java社區以及媒體發起鬧事,陰謀論其為政治謀殺,幾大公司是的 迫于形象,重新投票使得JDO被通過,但JDO這種靜態AOP叫雕蟲小計式技術,不單開發過程不方便,而且會使得"enhance"之后的代碼不可調試。 這完全是對開發者不友好的技術,沒有前途的技術,竟然會有人為它在JCP投票不通過鳴不平。這件事情使得我更堅信一點,不要相信那些技術編輯的判斷力。

    3、 AOP。也是最近這幾年流行的一個名詞了。起了一個和OOP相似的名字,但是和偉大的OOP相比,它完全不算是什么。AOP只是一種很小很小的技巧而已, 靜態的AOP是黑客式的插入代碼,會導致代碼不可調試,動態的AOP能力有限,AOP最常被引用例子“日志AOP”是不合適,有用的日志通常是精心設計 的,AOP方式的日志在生產環境中基本上是不可用。OO這么多年,這么為偉大,人們總是希望自己能做點什么和偉大的OO相比,于是命名為AOP,這是一個 可笑的名字,前些年還有人談論面向對象的未來是面向事實,也是同樣的可笑。AOP有價值,但它是一種小技巧,和名字不般配。

    --------------

    目前在流行,但是可能是不理智的技術:

    1、hibernate之類的ORM,試圖以面向對象方式操作數據,和面向對象數據庫一樣,重蹈覆轍。
    2、Ruby,一個小腳本語言,只是因為動態類型、mixin之類的功能,還沒有被證明有生產力,有效益可用的腳本語言,就被媒體吹到天上去。Ruby有價值,但是最終結果會離大家的期待相差甚遠。
    posted @ 2008-02-02 02:56 溫少的日志 閱讀(5259) | 評論 (19)編輯 收藏
     



    中國最大的在線記賬及商務管理平臺—金蝶“友商網”(
    www.youshang.com)正式上線!請立刻體驗!
    posted @ 2007-11-29 15:42 溫少的日志 閱讀(1472) | 評論 (13)編輯 收藏
     
         摘要: 本文描述一種ID生成算法  閱讀全文
    posted @ 2007-11-16 07:09 溫少的日志 閱讀(2732) | 評論 (8)編輯 收藏
     
         摘要: 本文介紹流行的非阻塞算法關鍵思想Compare And Set在數據庫開發中的應用  閱讀全文
    posted @ 2007-11-13 06:33 溫少的日志 閱讀(1457) | 評論 (4)編輯 收藏
     
    由于在實際工作中使用到了mina,所以一直關注其mail-list。

    最近mina的mail-list討論的一個問題,就是提供的manual close connector,這個問題可害慘我了。

    原來的Connector,無論是SocketConnector或者VmPipeConnector,都是沒有提供close方法的,而且不會自動釋放。

    原來做得一個網絡程序客戶端,每次重新創建的時候,都會new SocketConnector,可是,SocketConnector不會被GC回收的,所使用的線程和內存都不會自動釋放,這個程序在服務器斷開時會重連,于是,當服務器重啟或者網絡中斷時,內存泄漏就產生了,程序慢慢的占用更多的內存,直至崩潰!

    解決此問題的辦法就是,要么使用Singleton,要么使用即將發布的1.1.3!


    溫少 2007-09-29 21:08 發表評論
    posted @ 2007-09-29 21:12 溫少的日志 閱讀(1205) | 評論 (0)編輯 收藏
     
    使用maven2一段時間了,我基本把我自己能夠遷移的project都轉換為maven2 project,以下是我的一點感想。

    (原作者溫少,轉載請注明)

    亂世盼英雄


    現在的軟件開發,比過去的軟件開發要復雜得多。包括在參與開發的人數、代碼規模、復雜的需求、依賴包的復雜性、使用到更多的技術、多個項目之間的復雜依賴關系。

    現在的開發人員,要掌握的技術要比過去的開發人員要多,不是現在的開發人員比以前的開發人員本身更優秀,而是擁有更多的資料、更多的學習機會、更多更大規模的時間,同時軟件行業也在發展。說一句題外話,老程序員,如果不與時俱進,靠老本,是無法和新一代程序員競爭的,當然,老程序員,擁有更多的經驗,掌握新技術的速度更快,這又是另外一回事。

    開發人員掌握的技術更復雜了,項目用得的技術自然也是更復雜,例如一個web項目,可能使用到很多技術,面向對象、泛型、or-mapping、依賴注入(spring-framework)、全文檢索(lucene)、數據庫、集群、工作流、web service等等。

    由于使用了多種技術,這些技術可能是JDK提供的,也可能是第三方開源組織提供的,或者不同的商業公司提供的。

    于是出現了一個新的難題,就是包依賴復雜性。以前,你很難想象你的代碼依賴數十個不同開源組織、商業公司提供的庫。例如,我們經常使用的log4j、junit、easymock、ibatis、springframework,每個組件都有悠久的歷史,存在不同的版本,他們之間版本還有依賴關系。

    項目依賴的復雜性,經常的,一個較大部門有10-30個項目是常事,項目之間有不同版本的依賴關系,部門與部門之間的項目也存在復雜的版本依賴關系。

    Eclipse本身提供Project的依賴,但是簡單的依賴顯然解決不了問題。例如Project B依賴Project A,Project A依賴第三方的jar包abc-1.0.jar,那么需要在兩個項目的lib下都存放abc-1.0.jar,這產生冗余,當Project數量多起來,這個冗余就產生了管理問題,如果需要將abc-1.0.jar升級為abc-1.1.jar,則需要在兩個Project中同時修改,如果Project數量達到10個以上,而且是不同項目組維護的項目,這個就是非常麻煩的事情。而且Project A修改依賴,為啥需要Project B也作相應的修改呢?

    需要解決此問題,就需要在Project A的包中描述其依賴庫的信息,例如在META-INFO記錄所以來的abc-1.0.jar等。Eclipse的plug-in擁有類似的方案,但是這樣一來,就使得開發Project B的項目組,需要把Project A的代碼從源代碼庫中check out出來。在依賴鏈末端的項目組是很慘的。

    由于Project數量眾多,關系復雜,dailybuild的ant腳本編寫成了很麻煩的事情,使用Project依賴的方式,更加使得編寫dailybuild ant script是非常痛苦的事情。

    當然也可以不使用project依賴的方式,而使用artifact lib的依賴方式,但是artifact lib的依賴方式,就是同時修改多個project,互相調試時帶來了痛苦。

    在以前,我們面臨這些問題時,唯一的感覺就是,這事情TMD的太麻煩,幾乎是失控了。

    maven的出現,解決這種問題看到了希望。maven出現的原因就是,現在的開發管理復雜度達到了一定程序,需要專門的開發管理工具,這樣的工具需要涵蓋開發的各個階段,包括工程建立、配置依賴管理、編譯、測試、產生分析報告、部署、產生制品等階段。目前,各個階段的工具都存在,但是不是集成的,對使用帶來了很大麻煩。maven集成了這些工具,提高了統一的環境,使得使用更簡單。

    現在maven非常流行了,apache上所有java project都已經build by maven,其他跟進的開源項目非常多,例如mule、hibernat等等,商業公司也很多在采用,sun公司提供有maven2 repository。

    現在,2007年,如果你還沒采用maven project,你可能需要思考一下,是否你使用了不恰當的方式管理的代碼,或者你落伍了?

    maven的一些常用任務

    compile 編譯代碼
    test 運行單元測試
    package 打包代碼
    site 產生報告,例如java doc、junit的通過率報告和覆蓋率報告、findbugs的分析報告等等。
    assembly 使用需求產生assembly,例如把生成一個程序目錄,包括bin、config、lib、logs,把依賴包放在lib中。
    deploy 部署制品到repository中。

    這些都是常用的任務,在以前編寫腳本很麻煩,現在在maven中,一切都是很簡單,需要仔細設置時功能又強大到令人驚嘆,例如site的fml,assembly。

    maven資源庫

    maven官方提供了一個常用lib的資源庫,包括apache的所有java項目,開源常用的基本都能夠找到,例如mule、c3p0、easymock、hibernate、springframework、json等等,版本齊全,任你挑選。

    可以部署本地資源庫代理提高下載速度。使用maven proxy。

    maven體系結構


    maven使用plug-in的體系,使用很好的自動更新策略,本身用到的jar都是lazy download的,可以指定download的repository。這樣,初始下載的maven是一個很小的程序,使用的時候從本地的資源庫或者本地代理資源庫高速下載lib。maven的插件體系,充分利用了internet的資源豐富和局域網的高速帶寬,使用本地repository時,可以享受到每秒鐘數M的下載速度,感覺就是,人生真是美妙!

    elcipse的plug-in體系,就不是那么好用了,我們使用eclipse的find and install功能下載或者更新插件時,慢如蝸牛,依賴缺失時的煩惱,更新一個plug-in,可能耗費你數個小時,第三方的plug-in的下載服務器可能更慢,例如subversive的plugin-in,有一次我花了兩天還沒下載好,只好使用下載工具下載好,copy到plug-in目錄下。此時,我們總是感嘆,人生總是有很多煩惱事啊!

    相比之下,高下立判!在此我不是說eclipse的plug-in體系結構設計不好,eclipse的插件體系非常優秀,但是還有很大改進空間!




    溫少 2007-09-24 08:34 發表評論
    posted @ 2007-09-24 08:34 溫少的日志 閱讀(2922) | 評論 (7)編輯 收藏
     
    在beep4j上作了一些修改,并且在此之上實現了一個基于BEEP協議的服務器框架。

    BEEP協議提供了Session、Channel、Greeting、Profile、Frame等概念,這些基礎概念之上,很容易進行更高級的應用層協議設計。

    BEEP協議的特征和能力


    長連接
    對等通訊
    請求\應答式交互
    在一個Session中創建多個獨立的傳輸通道(Channel)
    在一個通道中進行多個異步請求(滑動窗口)
    可以使用不同的消息編碼方式,包括二進制、文本、XML等,類似SMTP的MIME,使得可以在高效的二進制、易懂的文本之間作出選擇。

    這是一個在傳輸層和應用層之間的協議,應用場景很廣泛,RFC標準化,官方網站為http://www.beepcore.org/。很多公司都有相應的支持,包括IBM。在不同語言下都是相應的實現,包括C、Java、Python、Ruby、JavaScript Beep client等等。

    關于ContentType和Codec


    在Java程序之間通訊,前期可能不希望作更多的協議編碼、解碼工作,使用spring bean xml格式傳輸是一種方式。

    在一些對效率不是特別高,又不喜歡使用機器友好的XML的場景,可以使用JSON的編碼方式。

    在一些對效率要求很高的場景,ASN.1或者自定義的二進制編碼格式。

    甚至使用土土的序列化編碼方式





    溫少 2007-09-22 08:07 發表評論
    posted @ 2007-09-22 08:07 溫少的日志 閱讀(908) | 評論 (0)編輯 收藏
     

    匆忙寫成,以后會慢慢補充

    請用力一擊

    中等規模的并發程序設計
    http://www.cnblogs.com/Files/jobs/2007-5-9-concurrent-ppt.rar

    2007-5-10修改版(帶參考文檔)
    http://www.cnblogs.com/Files/jobs/2007-5-10-concurrent-ppt.rar

    posted @ 2007-05-08 08:15 溫少的日志 閱讀(571) | 評論 (1)編輯 收藏
     
    2007年4月刊《程序員》,專題為“多核時下的軟件開發”。《程序員》并非陽春白雪,它面向大眾程序員。面向大眾的《程序員》介紹多核、并發,也意味著并發程序設計的開始進入中國大眾程序員的視野。

    并發程序設計,在很多的書籍或者文章中,都會提到他的一個特點,復雜。這個特性,也導致了在以往并發程序設計只為高級程序員所專用。

    復雜度并非事物的固有屬性,并發程序設計的復雜,是我們主觀認為。我們認為并發程序設計復雜,是因為我們還沒有掌握一些使其簡單化、清晰化的方法。當我們掌握相關方法,研究徹底,并發就會變得簡單。這個過程已經開始了。

    以 往,我們需要直接使用一些低級并發概念來構造系統,不斷發明輪子,容易出錯,難以調試,這種的并發程序設計當然復雜,因此也只能為高級程序員所專用。如此 環境,就如同Dijkstra給我們帶來結構化程序設計之前的世界一般。很幸運的是,一些軟件業的先驅們,已經抽象出一些概念,能夠使得并發程序設計簡單 化,清晰化。例如Future、Lock-free思想等。

    在主流編程語言中,Java走在最前頭,理念領先,提供了實用的庫。在 Java SE 5.0中就提供了util.concurent包,包括了Future、Executor、BlockingQueue等,一系列lock-free的數 據結構,例如ConcurrentMap。包括并發流程控制工具類:CountDownLatch、CycliBarrier。還有精巧好用的 DelayQueue(參考我之前寫過的文章http: //www.cnblogs.com/jobs/archive/2007/04/27/730255.html)。使用這些概念以及提供的模式,能夠使 得編寫并發程序簡單化。

    C++中,Herb Sutter在Visual C++中加入了很多支持并發的語法特性,包括atomic、future等。boost的線程庫開始引入了第一個高級概念barrier。

    Windows 平臺本身提供了功能強大的并發API,包括WaitForSingle系列,WaitForMulti系列,Auto和Manual模式的Event等 等。.NET平臺基本沒有任何自有的并發庫和工具類,完全是Windows API的簡單封裝。可以這么說,.NET的類庫沒有為并發作任何事情,完全吃Windows API的老本。

    如同Herb Sutter認為,我們很幸運處于并經歷這個軟件大變革(并發)。并發進入主流這個過程將會延續數年,Herb Sutter認為是2007-2012。
    參考我以前寫的一篇文章(Herb Sutter的一些觀點 http://www.cnblogs.com/jobs/archive/2006/11/12/558078.html)

    類 似的場景也有,早期面向對象技術,也只為少數高級程序員所掌握,現在剛入門的程序員都能說上一大通。數據結構算法也是,早期只為少數優秀程序員所掌握,但 現在主流的開發環境中就包括了主要的數據結構和算法,會用的人一把一把,會用List、Hashtable、快速排序一點也不酷。并發程序設計也一樣,將 不再是陽春白雪!

    面向對象技術在最初在Simula語言中引進,顧名思義,最初樸素的面向對象思想就是模擬,在程序中模擬真實世界。這種 “模擬”,使得程序的組織清晰化,簡單化。但真實世界是充滿著并發。真實世界的并發要比虛擬環境中的并發要復雜的多,但是人們輕松應付,由此,我們有足夠 的理由相信,并發程序設計將不會是一種復雜難掌握的技術。
    posted @ 2007-05-01 08:54 溫少的日志 閱讀(1405) | 評論 (2)編輯 收藏
     

    我們談一下實際的場景吧。我們在開發中,有如下場景

    a) 關閉空閑連接。服務器中,有很多客戶端的連接,空閑一段時間之后需要關閉之。
    b) 緩存。緩存中的對象,超過了空閑時間,需要從緩存中移出。
    c) 任務超時處理。在網絡協議滑動窗口請求應答式交互時,處理超時未響應的請求。

    一種笨笨的辦法就是,使用一個后臺線程,遍歷所有對象,挨個檢查。這種笨笨的辦法簡單好用,但是對象數量過多時,可能存在性能問題,檢查間隔時間不好設置,間隔時間過大,影響精確度,多小則存在效率問題。而且做不到按超時的時間順序處理。

    這場景,使用DelayQueue最適合了。

    DelayQueue 是java.util.concurrent中提供的一個很有意思的類。很巧妙,非常棒!但是java doc和Java SE 5.0的source中都沒有提供Sample。我最初在閱讀ScheduledThreadPoolExecutor源碼時,發現DelayQueue 的妙用。隨后在實際工作中,應用在session超時管理,網絡應答通訊協議的請求超時處理。

    本文將會對DelayQueue做一個介紹,然后列舉應用場景。并且提供一個Delayed接口的實現和Sample代碼。

    DelayQueue是一個BlockingQueue,其特化的參數是Delayed。(不了解BlockingQueue的同學,先去了解BlockingQueue再看本文)
    Delayed擴展了Comparable接口,比較的基準為延時的時間值,Delayed接口的實現類getDelay的返回值應為固定值(final)。DelayQueue內部是使用PriorityQueue實現的。

    DelayQueue = BlockingQueue + PriorityQueue + Delayed

    DelayQueue的關鍵元素BlockingQueue、PriorityQueue、Delayed。可以這么說,DelayQueue是一個使用優先隊列(PriorityQueue)實現的BlockingQueue,優先隊列的比較基準值是時間。

    他們的基本定義如下
    public interface Comparable<T> {
        
    public int compareTo(T o);
    }

    public interface Delayed extends Comparable<Delayed> {
        
    long getDelay(TimeUnit unit);
    }

    public class DelayQueue<extends Delayed> implements BlockingQueue<E> { 
        
    private final PriorityQueue<E> q = new PriorityQueue<E>();
    }

    DelayQueue內部的實現使用了一個優先隊列。當調用DelayQueue的offer方法時,把Delayed對象加入到優先隊列q中。如下:
    public boolean offer(E e) {
        
    final ReentrantLock lock = this.lock;
        lock.lock();
        
    try {
            E first 
    = q.peek();
            q.offer(e);
            
    if (first == null || e.compareTo(first) < 0)
                available.signalAll();
            
    return true;
        } 
    finally {
            lock.unlock();
        }
    }

    DelayQueue的take方法,把優先隊列q的first拿出來(peek),如果沒有達到延時閥值,則進行await處理。如下:
    public E take() throws InterruptedException {
        
    final ReentrantLock lock = this.lock;
        lock.lockInterruptibly();
        
    try {
            
    for (;;) {
                E first 
    = q.peek();
                
    if (first == null) {
                    available.await();
                } 
    else {
                    
    long delay =  first.getDelay(TimeUnit.NANOSECONDS);
                    
    if (delay > 0) {
                        
    long tl = available.awaitNanos(delay);
                    } 
    else {
                        E x 
    = q.poll();
                        
    assert x != null;
                        
    if (q.size() != 0)
                            available.signalAll(); 
    // wake up other takers
                        return x;

                    }
                }
            }
        } 
    finally {
            lock.unlock();
        }
    }

    -------------------

    以下是Sample,是一個緩存的簡單實現。共包括三個類Pair、DelayItem、Cache。如下:

    public class Pair<K, V> {
        
    public K first;

        
    public V second;
        
        
    public Pair() {}
        
        
    public Pair(K first, V second) {
            
    this.first = first;
            
    this.second = second;
        }
    }

    --------------
    以下是Delayed的實現
    import java.util.concurrent.Delayed;
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.atomic.AtomicLong;

    public class DelayItem<T> implements Delayed {
        
    /** Base of nanosecond timings, to avoid wrapping */
        
    private static final long NANO_ORIGIN = System.nanoTime();

        
    /**
         * Returns nanosecond time offset by origin
         
    */
        
    final static long now() {
            
    return System.nanoTime() - NANO_ORIGIN;
        }

        
    /**
         * Sequence number to break scheduling ties, and in turn to guarantee FIFO order among tied
         * entries.
         
    */
        
    private static final AtomicLong sequencer = new AtomicLong(0);

        
    /** Sequence number to break ties FIFO */
        
    private final long sequenceNumber;

        
    /** The time the task is enabled to execute in nanoTime units */
        
    private final long time;

        
    private final T item;

        
    public DelayItem(T submit, long timeout) {
            
    this.time = now() + timeout;
            
    this.item = submit;
            
    this.sequenceNumber = sequencer.getAndIncrement();
        }

        
    public T getItem() {
            
    return this.item;
        }

        
    public long getDelay(TimeUnit unit) {
            
    long d = unit.convert(time - now(), TimeUnit.NANOSECONDS);
            
    return d;
        }

        
    public int compareTo(Delayed other) {
            
    if (other == this// compare zero ONLY if same object
                return 0;
            
    if (other instanceof DelayItem) {
                DelayItem x 
    = (DelayItem) other;
                
    long diff = time - x.time;
                
    if (diff < 0)
                    
    return -1;
                
    else if (diff > 0)
                    
    return 1;
                
    else if (sequenceNumber < x.sequenceNumber)
                    
    return -1;
                
    else
                    
    return 1;
            }
            
    long d = (getDelay(TimeUnit.NANOSECONDS) - other.getDelay(TimeUnit.NANOSECONDS));
            
    return (d == 0? 0 : ((d < 0? -1 : 1);
        }
    }



    以下是Cache的實現,包括了put和get方法,還包括了可執行的main函數。
    import java.util.concurrent.ConcurrentHashMap;
    import java.util.concurrent.ConcurrentMap;
    import java.util.concurrent.DelayQueue;
    import java.util.concurrent.TimeUnit;
    import java.util.logging.Level;
    import java.util.logging.Logger;

    public class Cache<K, V> {
        
    private static final Logger LOG = Logger.getLogger(Cache.class.getName());

        
    private ConcurrentMap<K, V> cacheObjMap = new ConcurrentHashMap<K, V>();

        
    private DelayQueue<DelayItem<Pair<K, V>>> q = new DelayQueue<DelayItem<Pair<K, V>>>();

        
    private Thread daemonThread;

        
    public Cache() {

            Runnable daemonTask 
    = new Runnable() {
                
    public void run() {
                    daemonCheck();
                }
            };

            daemonThread 
    = new Thread(daemonTask);
            daemonThread.setDaemon(
    true);
            daemonThread.setName(
    "Cache Daemon");
            daemonThread.start();
        }

        
    private void daemonCheck() {

            
    if (LOG.isLoggable(Level.INFO))
                LOG.info(
    "cache service started.");

            
    for (;;) {
                
    try {
                    DelayItem
    <Pair<K, V>> delayItem = q.take();
                    
    if (delayItem != null) {
                        
    // 超時對象處理
                        Pair<K, V> pair = delayItem.getItem();
                        cacheObjMap.remove(pair.first, pair.second); 
    // compare and remove
                    }
                } 
    catch (InterruptedException e) {
                    
    if (LOG.isLoggable(Level.SEVERE))
                        LOG.log(Level.SEVERE, e.getMessage(), e);
                    
    break;
                }
            }

            
    if (LOG.isLoggable(Level.INFO))
                LOG.info(
    "cache service stopped.");
        }

        
    // 添加緩存對象
        public void put(K key, V value, long time, TimeUnit unit) {
            V oldValue 
    = cacheObjMap.put(key, value);
            
    if (oldValue != null)
                q.remove(key);

            
    long nanoTime = TimeUnit.NANOSECONDS.convert(time, unit);
            q.put(
    new DelayItem<Pair<K, V>>(new Pair<K, V>(key, value), nanoTime));
        }

        
    public V get(K key) {
            
    return cacheObjMap.get(key);
        }

        
    // 測試入口函數
        public static void main(String[] args) throws Exception {
            Cache
    <Integer, String> cache = new Cache<Integer, String>();
            cache.put(
    1"aaaa"3, TimeUnit.SECONDS);

            Thread.sleep(
    1000 * 2);
            {
                String str 
    = cache.get(1);
                System.out.println(str);
            }

            Thread.sleep(
    1000 * 2);
            {
                String str 
    = cache.get(1);
                System.out.println(str);
            }
        }
    }

    運行Sample,main函數執行的結果是輸出兩行,第一行為aaa,第二行為null。
    posted @ 2007-04-27 20:04 溫少的日志 閱讀(2022) | 評論 (2)編輯 收藏
    僅列出標題
    共8頁: 上一頁 1 2 3 4 5 6 7 8 下一頁 
     
    主站蜘蛛池模板: 亚洲精品国产国语| 综合亚洲伊人午夜网| 亚洲综合色7777情网站777| 免费看污成人午夜网站| 在线精品亚洲一区二区| 四虎永久免费地址在线网站| 国产91成人精品亚洲精品| 在线精品亚洲一区二区三区| 久久爰www免费人成| 亚洲an日韩专区在线| 免费A级毛片无码A∨男男| 日韩精品无码免费专区午夜不卡| 亚洲人成网站影音先锋播放| 最近免费中文字幕4| 一级做a爰全过程免费视频毛片| 亚洲国产精品无码久久SM| 114一级毛片免费| 国产亚洲精品美女久久久久| 亚洲日韩中文字幕在线播放| 美女视频黄a视频全免费网站一区| 亚洲一区二区三区香蕉| 亚洲视频在线免费看| 一级做a爰黑人又硬又粗免费看51社区国产精品视 | 日韩中文无码有码免费视频 | 亚洲国产人成精品| 成人浮力影院免费看| 97在线免费观看视频| 日本亚洲中午字幕乱码| 亚洲在成人网在线看| 亚洲av无码一区二区乱子伦as | 亚洲中文久久精品无码| 高清国语自产拍免费视频国产| 午夜影院免费观看| 国产一级婬片A视频免费观看| 亚洲精品一卡2卡3卡四卡乱码| 久久精品国产亚洲AV高清热| 久久影院亚洲一区| 国产一级淫片视频免费看| 成人av免费电影| 国色精品卡一卡2卡3卡4卡免费| 日韩精品久久久久久免费|