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

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

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

    神奇好望角 The Magical Cape of Good Hope

    庸人不必自擾,智者何需千慮?
    posts - 26, comments - 50, trackbacks - 0, articles - 11
      BlogJava :: 首頁 ::  :: 聯(lián)系 :: 聚合  :: 管理

    2012年1月19日

    21 世紀初,Spring 框架的誕生和崛起讓沉重而腐朽的 J2EE 遭到了當頭棒喝,隨后大批開發(fā)人員轉(zhuǎn)投 Spring 陣營,呼吸間就讓 J2EE 陣營大傷元氣。然而這種命懸一線的危機并沒有造成毀滅性的打擊,尤其是對于 Java 這種提倡開放的平臺而言,取長補短,互相促進才是正道。于是,JCP 委員會痛定思痛,在 2006 年推出 Java EE 5 規(guī)范,主要是對 EJB 的開發(fā)進行了極大幅度的簡化。2008 年發(fā)布的 Java EE 6 引入了 CDI、BV、JAX-RS 等一系列新功能,并且以配置文件(profile)的方式讓 Java EE 向輕量級邁進了一步。特別有趣的是,Spring 框架也開始提供對某些 Java EE 注解的支持,是否標志著兩大陣營開始合流?Java EE 7 預(yù)定于今年下半年發(fā)布,目標是支持云計算。最近幾年來,云計算一直被炒作,卻從來沒有一個準確的定義和規(guī)范,希望 Java EE 7 能夠在 Java 界扭轉(zhuǎn)這種尷尬的局面。

    下面開始詳細列舉 Java EE 7 的新功能前瞻,數(shù)據(jù)來源于《Java Magazine 2012-01/02》中的《Cloud/Java EE: Looking Ahead to Java EE 7》一文。Java EE 7 是以“日期驅(qū)動”的方式開發(fā)的,也就是說,在計劃日期到達前沒有完成的功能都將被推遲到 Java EE 8。

    Java EE 7(JSR-342)

    • 主題:讓應(yīng)用程序能夠在私有或公共云上容易地運行。
    • 該平臺將定義一個應(yīng)用程序元數(shù)據(jù)描述符,以描述 PaaS 執(zhí)行環(huán)境(例如多租戶、資源共享、服務(wù)質(zhì)量,以及應(yīng)用程序間的依賴)。
    • 支持 HTML5、WebSocket、JSON 等新標準,并為它們一一提供 API。
    • 消除受管 Bean、EJB、Servlet、JSF、CDI 和 JAX-RS 之間不一致的地方。
    • 可能在 Web 配置文件中包含 JAX-RS 2.0 和 JMS 2.0 API 修訂版。
    • 更新一些現(xiàn)有的技術(shù),可能引入用于 Java EE 的并發(fā)工具(JSR-236)和 JCache(JSR-107)。

    Java Persistence 2.1(JSR-338)

    • 支持多租戶。
    • 支持存儲過程和廠商函數(shù)。
    • 用規(guī)則(Criteria)進行更新和刪除。
    • 支持數(shù)據(jù)庫大綱(Scheme)的生成。
    • 持久化上下文的同步。
    • 偵聽器中的 CDI 注入。

    JAX-RS 2.0: The Java API for RESTful Web Services(JSR-339)

    • 客戶端 API——底層使用構(gòu)建者模式,可能提供上層封裝。
    • 超媒體——輕松創(chuàng)建和處理關(guān)聯(lián)了資源的鏈接。
    • 使用 Bean 驗證框架來驗證表單或查詢參數(shù)。
    • @Inject 更緊密集成。
    • 服務(wù)端的異步請求處理。
    • 使用“qs”進行服務(wù)端的內(nèi)容協(xié)商。

    Java Servlet 3.1(JSR-340)

    • 為 Web 應(yīng)用程序優(yōu)化 PaaS 模型。
    • 用于安全、會話和資源的多租戶。
    • 基于 NIO2 的異步 I/O。
    • 簡化的異步 Servlet。
    • 利用 Java EE 并發(fā)工具。
    • 支持 WebSocket。

    Expression Language 3.0(JSR-341)

    • ELContext 分離為解析和求值上下文。
    • 可定制的 EL 強迫規(guī)則。
    • 在 EL 表達式中直接引用靜態(tài)方法和成員。
    • 添加運算符,例如等于、字符串連接和取大小。
    • 與 CDI 集成,例如在表達式求值前/中/后生成事件。

    Java Message Service 2.0(JSR-343)

    • 簡化開發(fā)——改變 JMS 編程模型,讓應(yīng)用程序開發(fā)變得更加簡單容易。
    • 清除/澄清現(xiàn)有規(guī)范中的模糊之處。
    • 與 CDI 集成。
    • 澄清 JMS 和其他 Java EE 規(guī)范之間的關(guān)系。
    • 新的強制性 API允許任何 JMS 提供者能與任何 Java EE 容器集成。
    • 來自平臺的多租戶和其他云相關(guān)的功能。

    JavaServer Faces 2.2(JSR-344)

    • 簡化開發(fā)——使配置選項動態(tài)化,使復(fù)合組件中的 cc:interface 可選,F(xiàn)acelet 標記庫的速記 URL,與 CDI 集成,JSF 組件的 OSGi 支持。
    • 支持 Portlet 2.0 橋(JSR-329)的實現(xiàn)。
    • 支持 HTML5 的功能,例如 HTML5 表單、元數(shù)據(jù)、頭部和區(qū)段內(nèi)容模型。
    • 流管理,頁面導(dǎo)航事件的偵聽器,以及 fileUploadBackButton 等新組件。

    Enterprise JavaBeans 3.2(JSR-345)

    • 增強 EJB 架構(gòu)以支持 PaaS,例如多租戶。
    • 對在 EJB 外使用容器管理的事務(wù)進行工廠化。
    • 更進一步使用注解。
    • 與平臺中的其他規(guī)范對齊和集成。

    Contexts and Dependency Injection 1.1(JSR-346)

    • 攔截器的全局排序和管理內(nèi)建上下文的裝飾器 API。
    • 可在 Java EE 容器外啟動的嵌入式模式。
    • 聲明式地控制歸檔中的哪些包和 Bean 將被掃描。
    • 注入日志之類的靜態(tài)成員。
    • 將 Servlet 事件作為 CDI 事件發(fā)送。

    Bean Validation 1.1(JSR-349)

    • 與其他 Java EE 規(guī)范集成。
    • JAX-RS:在 HTTP 調(diào)用中驗證參數(shù)和返回值。
    • JAXB:將約束條件轉(zhuǎn)換到 XML 模式描述符中。
    • 方法級別的驗證。
    • 在組集合上應(yīng)用約束條件。
    • 擴展模型以支持“與”和“或”風(fēng)格的組合。

    JCache: Java Temporary Caching API(JSR-107)

    • 在內(nèi)存中暫存 Java 對象的 API 和語義,包括對象的創(chuàng)建、共享訪問、緩存池、失效,以及跨 JVM 的一致性。

    Java State Management(JSR-350)

    • 應(yīng)用程序和 Java EE 容器可使用該 API 將狀態(tài)管理的任務(wù)交給具有不同 QoS 特征的第三方提供者。
    • 基于 Java SE 的調(diào)用者可通過查詢狀態(tài)提供者來訪問狀態(tài)數(shù)據(jù)。
    • 可添加具有不同 QoS 的提供者,API 調(diào)用者能夠按自己的規(guī)則進行查詢。

    Batch Applications for the Java Platform(JSR-352)

    • 用于批處理應(yīng)用程序的編程模型,以及用于調(diào)度和執(zhí)行工作的運行時。
    • 為標準編程模型定義批處理工作、批處理工作步驟、批處理應(yīng)用程序、批處理執(zhí)行器和批處理工作管理器。

    Concurrency Utilities for Java EE(JSR-236)

    • 提供一個整潔、簡單且獨立的 API,使其能用于任何 Java EE 容器中。

    Java API for JSON Processing(JSR-353)

    • 處理 JSON 的 Java API。

    posted @ 2012-02-13 22:23 蜀山兆孨龘 閱讀(5757) | 評論 (0)編輯 收藏

    ForkJoinPool 是 Java SE 7 新功能“分叉/結(jié)合框架”的核心類,現(xiàn)在可能乏人問津,但我覺得它遲早會成為主流。分叉/結(jié)合框架是一個比較特殊的線程池框架,專用于需要將一個任務(wù)不斷分解成子任務(wù)(分叉),再不斷進行匯總得到最終結(jié)果(結(jié)合)的計算過程。比起傳統(tǒng)的線程池類 ThreadPoolExecutorForkJoinPool 實現(xiàn)了工作竊取算法,使得空閑線程能夠主動分擔(dān)從別的線程分解出來的子任務(wù),從而讓所有的線程都盡可能處于飽滿的工作狀態(tài),提高執(zhí)行效率。

    ForkJoinPool 提供了三類方法來調(diào)度子任務(wù):

    execute 系列
    異步執(zhí)行指定的任務(wù)。
    invokeinvokeAll
    執(zhí)行指定的任務(wù),等待完成,返回結(jié)果。
    submit 系列
    異步執(zhí)行指定的任務(wù)并立即返回一個 Future 對象。

    子任務(wù)由 ForkJoinTask 的實例來代表。它是一個抽象類,JDK 為我們提供了兩個實現(xiàn):RecursiveTaskRecursiveAction,分別用于需要和不需要返回計算結(jié)果的子任務(wù)。ForkJoinTask 提供了三個靜態(tài)的 invokeAll 方法來調(diào)度子任務(wù),注意只能在 ForkJoinPool 執(zhí)行計算的過程中調(diào)用它們。

    ForkJoinPoolForkJoinTask 還提供了很多讓人眼花繚亂的公共方法,其實它們大多數(shù)都是其內(nèi)部實現(xiàn)去調(diào)用的,對于應(yīng)用開發(fā)人員來說意義不大。

    下面以統(tǒng)計 D 盤文件個數(shù)為例。這實際上是對一個文件樹的遍歷,我們需要遞歸地統(tǒng)計每個目錄下的文件數(shù)量,最后匯總,非常適合用分叉/結(jié)合框架來處理:

    // 處理單個目錄的任務(wù)
    public class CountingTask extends RecursiveTask<Integer> {
        private Path dir;
    
        public CountingTask(Path dir) {
            this.dir = dir;
        }
    
        @Override
        protected Integer compute() {
            int count = 0;
            List<CountingTask> subTasks = new ArrayList<>();
    
            // 讀取目錄 dir 的子路徑。
            try (DirectoryStream<Path> ds = Files.newDirectoryStream(dir)) {
                for (Path subPath : ds) {
                    if (Files.isDirectory(subPath, LinkOption.NOFOLLOW_LINKS)) {
                        // 對每個子目錄都新建一個子任務(wù)。
                        subTasks.add(new CountingTask(subPath));
                    } else {
                        // 遇到文件,則計數(shù)器增加 1。
                        count++;
                    }
                }
    
                if (!subTasks.isEmpty()) {
                    // 在當前的 ForkJoinPool 上調(diào)度所有的子任務(wù)。
                    for (CountingTask subTask : invokeAll(subTasks)) {
                        count += subTask.join();
                    }
                }
            } catch (IOException ex) {
                return 0;
            }
            return count;
        }
    }
    
    // 用一個 ForkJoinPool 實例調(diào)度“總?cè)蝿?wù)”,然后敬請期待結(jié)果……
    Integer count = new ForkJoinPool().invoke(new CountingTask(Paths.get("D:/")));
        

    在我的筆記本上,經(jīng)多次運行這段代碼,耗費的時間穩(wěn)定在 600 豪秒左右。普通線程池(Executors.newCachedThreadPool())耗時 1100 毫秒左右,足見工作竊取的優(yōu)勢。

    結(jié)束本文前,我們來圍觀一個最神奇的結(jié)果:單線程算法(使用 Files.walkFileTree(...))比這兩個都快,平均耗時 550 毫秒!這警告我們并非引入多線程就能優(yōu)化性能,并須要先經(jīng)過多次測試才能下結(jié)論。

    posted @ 2012-02-09 10:40 蜀山兆孨龘 閱讀(2681) | 評論 (2)編輯 收藏

    前面已經(jīng)看到,Socket 類的 getInputStream()getOutStream() 方法分別獲取套接字的輸入流和輸出流。輸入流用來讀取遠端發(fā)送過來的數(shù)據(jù),輸出流則用來向遠端發(fā)送數(shù)據(jù)。

    輸入流

    使用套接字的輸入流讀取數(shù)據(jù)時,當前線程會進入阻塞狀態(tài),直到套接字收到一些數(shù)據(jù)為止(亦即套接字的接收緩沖區(qū)有可用數(shù)據(jù))。該輸入流的 available() 方法只是返回接收緩沖區(qū)的可用字節(jié)數(shù)量,不可能知道遠端還要發(fā)送多少字節(jié)。使用輸入流的時候,最好先將它包裝為一個 BufferedInputStream,因為讀取接收緩沖區(qū)將導(dǎo)致 JVM 和底層系統(tǒng)之間的切換,應(yīng)當盡量減少切換次數(shù)以提高性能。BufferedInputStream 的緩沖區(qū)大小最好設(shè)為套接字接收緩沖區(qū)的大小。

    如果直接調(diào)用輸入流的 close() 方法來關(guān)閉它,則將導(dǎo)致套接字被關(guān)閉。對此,Socket 類提供了一個 shutdownInput() 方法來禁用輸入流。調(diào)用該方法后,每次讀操作都將返回 EOF,無法再讀取遠端發(fā)送的數(shù)據(jù)。對這個 EOF 的檢測,不同的輸入流包裝體現(xiàn)出不同的結(jié)果,可能讀到 -1 個字節(jié),可能讀到的字符串為 null,還可能收到一個 EOFException 等等。禁用輸入流后,遠端輸出流的行為是平臺相關(guān)的:

    • 在 BSD 平臺上,遠端的發(fā)送的數(shù)據(jù)能正常接收,然后直接丟棄。遠端無法知道本端的輸入流已禁用。這和 JDK 文檔描述的行為一致。
    • 在 WINSOCK 平臺上,遠端發(fā)送數(shù)據(jù)將會導(dǎo)致“連接被重置”的錯誤。
    • 在 Linux 平臺上,遠端發(fā)送的數(shù)據(jù)能繼續(xù)接收,直到套接字輸入緩沖區(qū)填滿,之后遠端再也無法發(fā)送數(shù)據(jù)(若使用阻塞模式則進入死鎖)。

    禁用輸入流這種技術(shù)并不常用。

    輸出流

    套接字的輸出操作實際上僅僅將數(shù)據(jù)寫到發(fā)送緩沖區(qū)內(nèi),當發(fā)送緩沖區(qū)填滿且上次的發(fā)送成功后,由底層系統(tǒng)負責(zé)發(fā)送。如果發(fā)送緩沖區(qū)的剩余空間不夠,當前線程就會阻塞。和輸入流類似,最好將輸出流包裝為 BufferedOutputStream

    如果套接字的雙發(fā)都使用 ObjectInputStreamObjectOutputStream 來讀寫 Java 對象,則必須先創(chuàng)建 ObjectOutputStream,因為 ObjectInputStream 在構(gòu)造的時候會試圖讀取對象頭部,如果雙發(fā)都先創(chuàng)建 ObjectInputStream,則會互相等待對方的輸出,造成死鎖:

    // 創(chuàng)建的順序不能顛倒!
    ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
    ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
        

    類似于輸入流,關(guān)閉輸出流也導(dǎo)致關(guān)閉套接字,所以 Socket 類同樣提供了一個 shutdownOutput() 來禁用輸出流。禁用輸出流后,已寫入發(fā)送緩沖區(qū)的數(shù)據(jù)會正常發(fā)送,之后的任何寫操作都會導(dǎo)致 IOException,且遠端的輸入流始終會讀到 EOF。禁用輸出流非常有用,例如套接字的雙發(fā)都在發(fā)送完畢數(shù)據(jù)后禁用輸入流,然后雙方都會收到 EOF,從而知道數(shù)據(jù)已經(jīng)全部交換完畢,可以安全關(guān)閉套接字。直接關(guān)閉套接字會同時關(guān)閉輸入流和輸出流,且斷開連接,達不到這種效果。

    使用流的阻塞套接字的優(yōu)缺點

    如果要使用流進行輸入和輸出,就只能用阻塞模式的套接字。這里總結(jié)一下阻塞套接字的優(yōu)缺點。先看看優(yōu)點:

    1. 編程模型簡單,非常適合初學(xué)者上手。
    2. 以裝飾器模式設(shè)計的 Java I/O 使得開發(fā)人員可以輕松地從 I/O 流讀寫任何類型的數(shù)據(jù)。

    但在性能方面有致命的缺點:

    1. 由于服務(wù)器套接字接受連接,以及套接字的讀寫都會阻塞,性能低下。
    2. 如果不對 I/O 流手動進行緩沖,則可能造成一次只處理一個字節(jié),性能低下。
    3. 服務(wù)器套接字每次只能接受一個連接,導(dǎo)致 JVM 和底層系統(tǒng)之間頻繁的調(diào)用切換,性能低下。

    下一篇文章開始探討使用基于 NIO 的套接字通道和緩沖區(qū)實現(xiàn)伸縮性更強的 TCP 套接字。

    posted @ 2012-01-19 14:37 蜀山兆孨龘 閱讀(2276) | 評論 (1)編輯 收藏

    主站蜘蛛池模板: 九九九精品视频免费| 久久夜色精品国产亚洲av| 中文字幕av免费专区| 香蕉大伊亚洲人在线观看| 国产亚洲高清不卡在线观看| 在线观看免费国产视频| 成年人网站免费视频| 日韩精品无码免费一区二区三区| 羞羞漫画小舞被黄漫免费| 亚洲一区AV无码少妇电影| 亚洲欧洲日本天天堂在线观看| 亚洲乱码中文字幕综合| 免费一级一片一毛片| 性生交片免费无码看人| 猫咪免费人成网站在线观看| 成全在线观看免费观看大全| 日韩毛片免费一二三| 国产亚洲精品2021自在线| 在线a亚洲老鸭窝天堂av高清| 亚洲成AV人片久久| 亚洲视频一区在线| 久久亚洲美女精品国产精品| 亚洲AV无码不卡在线播放| 国产亚洲婷婷香蕉久久精品| 伊人久久精品亚洲午夜| 中文字幕亚洲激情| 亚洲伊人久久大香线蕉综合图片 | 久久精品国产精品亚洲艾| 亚洲综合色自拍一区| 亚洲综合久久夜AV | 亚洲日韩在线中文字幕第一页| 国产免费卡一卡三卡乱码| 国产成人高清精品免费鸭子| 国产一级一片免费播放| 亚洲?V无码乱码国产精品| 亚洲国产综合人成综合网站| 亚洲女同成人AⅤ人片在线观看| 国产精品亚洲w码日韩中文| 国产精品亚洲精品日韩已满| 亚洲综合色婷婷七月丁香| 久久精品视频亚洲|