睫晉姬

          2010年7月29日 #

          如何獲取Sun推出的Java認(rèn)證指南

            Sun推出的專業(yè)認(rèn)證包括下列三種:

            ◆JAVA認(rèn)證考試

            對于JAVA程序設(shè)計員,Sun推出兩項認(rèn)證:

            Sun Certified JAVA Programmer(SCJP)

            Sun Certified JAVA Developer(SCJD)

            Java程序員的認(rèn)證Sun Certified JAVA Programmer(SCJP)課程:SL-275JAVA語言編程,考試號為310-025.

            java開發(fā)員認(rèn)證Sun Certified JAVA Deverloper(SCJD),認(rèn)證考試以Sun指定的javaSL-285為教材,機(jī)考部分的考試號為310-027。

            SCJP測驗JAVA程序設(shè)計概念及能力,內(nèi)容偏重于JAVA語法及JDK的內(nèi)容;SCJD則進(jìn)一步測試用JAVA開發(fā)應(yīng)用程序的能力,考試者必須先完成一個程序的設(shè)計方案,再回答與此方案相關(guān)的一些問題。

            ◆Solaris系統(tǒng)管理認(rèn)證考試

            對Solaris/SunOS系統(tǒng)管理員,Sun推出Certified Solaris Administrator(CSA)。CSA分別為兩個等級(PartI和PartII),測試對Solaris系統(tǒng)管理的了解程度。

            ◆Solaris網(wǎng)絡(luò)管理認(rèn)證考試

            為了測試使用者對于Solaris網(wǎng)絡(luò)管理能力,Sun推出Certified Network Administrator(CNA)。內(nèi)容包括基本網(wǎng)絡(luò)概念、RoutingandSubnet、Security、Performance、DNS、NIS+等。

            SunJava認(rèn)證是業(yè)界唯一經(jīng)Sun授權(quán)Java認(rèn)證培訓(xùn)。Sun認(rèn)證Java開發(fā)員考試內(nèi)容包括完整的Java應(yīng)用程序開發(fā),涉及數(shù)據(jù)庫、圖形用戶界面、網(wǎng)絡(luò)通信、平臺移植等各方面內(nèi)容,要求學(xué)員已通過Java程序員認(rèn)證。學(xué)習(xí)結(jié)束后,可參加全球連網(wǎng)考試。考試合格則由Sun公司頒發(fā)國際通用的Java開發(fā)員證書。

            Java語言在1995年發(fā)布以來,因其具有簡單性、跨平臺、面向?qū)ο蟮忍攸c,受到程序員們的歡迎,經(jīng)過這幾年的迅速發(fā)展,現(xiàn)在已經(jīng)成為和C++語言并列的主流開發(fā)語言。Java語言的廣泛使用,使得越來越多的人加入到Java語言的學(xué)習(xí)和應(yīng)用中來。

            在這些人當(dāng)中,許多人選擇了經(jīng)過Sun公司授權(quán)的Sun教育中心(ASEC)來學(xué)習(xí),因為和一些非授權(quán)的中心相比,只有ASEC受到Sun組合機(jī)床公司的關(guān)注和支持,他們可以提供最新的培訓(xùn)材料和Sun需要的精深技術(shù)資源。學(xué)員在那里可以學(xué)習(xí)到最新的Java技術(shù),更順利地通過SunJava的認(rèn)證考試。

            了解SunJava認(rèn)證課程

            Java不僅僅是一種編程語言,同時它也是一個開發(fā)和運(yùn)行的平臺,有自己完整的體系結(jié)構(gòu)。SunJava認(rèn)證課程從中選擇了最具有代表性的一些方面。

            SCJP(Sun Certified Java Programmer)可以說是各種Java認(rèn)證的基礎(chǔ),其對應(yīng)的最主要的學(xué)習(xí)課程是一門Java的基礎(chǔ)課程,也就是Java Programming Language(SL-275),這也是國內(nèi)的SCJP培訓(xùn)的標(biāo)準(zhǔn)課程。而SCJD(Sun Certified Java Developer)則可以看做是高級的Java技術(shù)培訓(xùn)認(rèn)證,其要求和難度都要高于SCJP,而且,如果你計劃獲得SCJD認(rèn)證,則要先獲得SCJP認(rèn)證資格。SCEA(Sun Certified Enterprise Architect for J2EE Technology)認(rèn)證的難度也不小,其學(xué)習(xí)課程主要有兩個:00-226O bject-Oriented Analysisand Design以及SL-425 Architectingand Designing J2EE Applications。SCWD(Sun Certified WebComponent Developer for Java2 Platform Enterprise Edition)是Sun新推出的Java認(rèn)證考試,主要面向使用JavaServlet以及JSP技術(shù)開發(fā)Web應(yīng)用程序的相關(guān)技術(shù)認(rèn)證。

            如何獲取Java認(rèn)證

            首先,你需要有充分的心理準(zhǔn)備,因為SunJava認(rèn)證考試非常嚴(yán)謹(jǐn),需要你具備充足的實踐經(jīng)驗才可能通過。

          posted @ 2010-07-29 16:10 睫晉姬 閱讀(263) | 評論 (0)編輯 收藏

          spring連接池配置詳解

            數(shù)據(jù)庫連接池概述:

            數(shù)據(jù)庫連接是一種關(guān)鍵的有限的昂貴的資源,這一點在多用戶的網(wǎng)頁應(yīng)用程序中體現(xiàn)得尤為突出。對數(shù)據(jù)庫連接的管理能顯著影響到整個應(yīng)用程序的伸縮性和健壯性,影響到程序的性能指標(biāo)。數(shù)據(jù)庫連接池正是針對這個問題提出來的。

            數(shù)據(jù)庫連接池負(fù)責(zé)分配、管理和釋放數(shù)據(jù)庫連接,它允許應(yīng)用程序重復(fù)使用一個現(xiàn)有的數(shù)據(jù)庫連接,而再不是重新建立一個;釋放空閑時間超過最大空閑時間的數(shù)據(jù)庫連接來避免因為沒有釋放數(shù)據(jù)庫連接而引起的數(shù)據(jù)庫連接遺漏。這項技術(shù)能明顯提高對數(shù)據(jù)庫操作的性能。

            數(shù)據(jù)庫連接池在初始化時將創(chuàng)建一定數(shù)量的數(shù)據(jù)庫連接放到連接池中,這些數(shù)據(jù)庫連接的數(shù)量是由最小數(shù)據(jù)庫連接數(shù)來設(shè)定的。無論這些數(shù)據(jù)庫連接是否被使用,連接池都將一直保證至少擁有這么多的連接數(shù)量。連接池的最大數(shù)據(jù)庫連接干洗設(shè)備數(shù)量限定了這個連接池能占有的最大連接數(shù),當(dāng)應(yīng)用程序向連接池請求的連接數(shù)超過最大連接數(shù)量時,這些請求將被加入到等待隊列中。數(shù)據(jù)庫連接池的最小連接數(shù)和最大連接數(shù)的設(shè)置要考慮到下列幾個因素:

            1) 最小連接數(shù)是連接池一直保持的數(shù)據(jù)庫連接,所以如果應(yīng)用程序?qū)?shù)據(jù)庫連接的使用量不大,將會有大量的數(shù)據(jù)庫連接資源被浪費(fèi);

            2) 最大連接數(shù)是連接池能申請的最大連接數(shù),如果數(shù)據(jù)庫連接請求超過此數(shù),后面的數(shù)據(jù)庫連接請求將被加入到等待隊列中,這會影響之后的數(shù)據(jù)庫操作。

            3) 如果最小連接數(shù)與最大連接數(shù)相差太大,那么最先的連接請求將會獲利,之后超過最小連接數(shù)量的連接請求等價于建立一個新的數(shù)據(jù)庫連接。不過,這些大于最小連接數(shù)的數(shù)據(jù)庫連接在使用完不會馬上被釋放,它將被放到連接池中等待重復(fù)使用或是空閑超時后被釋放。

            目前常用的連接池有:C3P0、DBCP、Proxool

            網(wǎng)上的評價是:

            C3P0比較耗費(fèi)資源,效率方面可能要低一點。

            DBCP在實踐中存在BUG,在某些種情會產(chǎn)生很多空連接不能釋放,Hibernate3.0已經(jīng)放棄了對其的支持。

            Proxool的負(fù)面評價較少,現(xiàn)在比較推薦它,而且它還提供即時監(jiān)控連接池狀態(tài)的功能,便于發(fā)現(xiàn)連接泄漏的情況。

            配置如下:

            1、在spring配置文件中,一般在applicationContext.xml中

            <bean id="DataSource" class="org.logicalcobwebs.proxool.ProxoolDataSource" destroy-method="shutdown">

            <property name="driver">

            <value>oracle.jdbc.driver.OracleDriver</value>

            </property>

            <property name="driverUrl">

            <value>jdbc:oracle:thin:xxxx/xxxx@192.168.0.XX:1521:server</value>

            </property>

            <property name="user">

            <value>xxxx</value>

            </property>

            <property name="password">

            <value>xxxx</value>

            </property>

            <property name="alias">

            <value>server</value>

            </property>

            <property name="houseKeepingSleepTime">

            <value>30000</value>

            </property>

            <property name="houseKeepingTestSql">

            <value>select 1 from dual</value>

            </property>

            <property name="testBeforeUse">

            <value>true</value>

            </property>

            <property name="testAfterUse">

            <value>true</value>

            </property>

            <property name="prototypeCount">

            <value>5</value>

            </property>

            <property name="maximumConnectionCount">

            <value>400</value>

            </property>

            <property name="minimumConnectionCount">

            <value>10</value>

            </property>

            <property name="statistics">

            <value>1m,15m,1d</value>

            </property>

            <property name="statisticsLogLevel">

            <value>ERROR</value>

            </property>

            <property name="trace">

            <value>true</value>

            </property>

            <property name="verbose">

            <value>false</value>

            </property>

            <property name="simultaneousBuildThrottle">

            <value>1600</value>

            </property>

            <property name="maximumActiveTime">

            <value>600000</value>

            </property>

            <property name="jmx">

            <value>false</value>

            </property>

            </bean>

            然后注入到sessionFactory中

            <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">

            <property name="dataSource" ref="DataSource"/>

            </bean>

            屬性列表說明:

            fatal-sql-exception: 它是一個逗號分割的信息片段.當(dāng)一個SQL異常發(fā)生時,他的異常信息將與這個信息片段進(jìn)行比較.如果在片段中存在,那么這個異常將被認(rèn)為是個致命錯誤(Fatal SQL Exception ).這種情況下,數(shù)據(jù)庫連接將要被放棄.無論發(fā)生什么,這個異常將會被重擲以提供給消費(fèi)者.用戶最好自己配置一個不同的異常來拋出.

            fatal-sql-exception-wrapper-class:正如上面所說,你最好配置一個不同的異常來重擲.利用這個屬性,用戶可以包裝SQLException,使他變成另外一個異常.這個異常或者繼承QLException或者繼承字RuntimeException.proxool自帶了2個實現(xiàn):'org.logicalcobwebs.proxool.FatalSQLException'和'org.logicalcobwebs.proxool.FatalRuntimeException'.后者更合適.

            house-keeping-sleep-time: house keeper 保留線程處于睡眠狀態(tài)的最長時間,house keeper 的職責(zé)就是檢查各個連接的狀態(tài),并判斷是否需要銷毀或者創(chuàng)建.

            house-keeping-test-sql:  如果發(fā)現(xiàn)了空閑的數(shù)據(jù)庫連接.house keeper 將會用這個語句來測試.這個語句最好非常快的被執(zhí)行.如果沒有定義,測試過程將會被忽略。

            injectable-connection-interface: 允許proxool實現(xiàn)被代理的connection對象的方法.

            injectable-statement-interface: 允許proxool實現(xiàn)被代理的Statement 對象方法.

            injectable-prepared-statement-interface: 允許proxool實現(xiàn)被代理的PreparedStatement 對象方法.

            injectable-callable-statement-interface: 允許proxool實現(xiàn)被代理的CallableStatement 對象方法.

            jmx: 如果屬性為true,就會注冊一個消息Bean到j(luò)ms服務(wù),消息Bean對象名: "Proxool:type=Pool, name=<alias>". 默認(rèn)值為false.

            jmx-agent-id: 一個逗號分隔的JMX代理列表(如使用MBeanServerFactory.findMBeanServer(String agentId)注冊的連接池。)這個屬性是僅當(dāng)"jmx"屬性設(shè)置為"true"才有效。所有注冊jmx服務(wù)器使用這個屬性是不確定的

            jndi-name: 數(shù)據(jù)源的名稱

            maximum-active-time: 如果housekeeper 檢測到某個線程的活動時間大于這個數(shù)值.它將會殺掉這個線程.所以確認(rèn)一下你的服務(wù)器的帶寬.然后定一個合適的值.默認(rèn)是5分鐘.

            maximum-connection-count: 最大的數(shù)據(jù)庫連接數(shù).

            maximum-connection-lifetime: 一個線程的最大壽命.

            minimum-connection-count: 最小的數(shù)據(jù)庫連接數(shù)

            overload-without-refusal-lifetime: 這可以幫助我們確定連接池的狀態(tài)。如果我們已經(jīng)拒絕了一個連接在這個設(shè)定值(毫秒),然后被認(rèn)為是超載。默認(rèn)為60秒。

            prototype-count: 連接池中可用的連接數(shù)量.如果當(dāng)前的連接池中的連接少于這個數(shù)值.新的連接將被建立(假設(shè)沒有超過最大可用數(shù)).例如.我們有3個活動連接2個可用連接,而我們的prototype-count是4,那么數(shù)據(jù)庫連接池將試圖建立另外2個連接.這和 minimum-connection-count不同. minimum-connection-count把活動的連接也計算在內(nèi).prototype-count 是spare connections 的數(shù)量.

            recently-started-threshold: 這可以幫助我們確定連接池的狀態(tài),連接數(shù)少還是多或超載。只要至少有一個連接已開始在此值(毫秒)內(nèi),或者有一些多余的可用連接,那么我們假設(shè)連接池是開啟的。默認(rèn)為60秒

            simultaneous-build-throttle: 這是我們可一次建立的最大連接數(shù)。那就是新增的連接請求,但還沒有可供使用的連接。由于連接可以使用多線程,在有限的時間之間建立聯(lián)系從而帶來可用連接,但是我們需要通過一些方式確認(rèn)一些線程并不是立即響應(yīng)連接請求的,默認(rèn)是10。

            statistics:  連接池使用狀況統(tǒng)計。 參數(shù)“10s,1m,1d”

            statistics-log-level: 日志統(tǒng)計跟蹤類型。 參數(shù)“ERROR”或 “INFO”

            test-before-use: 如果為true,在每個連接被測試前都會服務(wù)這個連接,如果一個連接失敗,那么將被丟棄,另一個連接將會被處理,如果所有連接都失敗,一個新的連接將會被建立。否則將會拋出一個SQLException異常。

            test-after-use: 如果為true,在每個連接被測試后都會服務(wù)這個連接,使其回到連接池中,如果連接失敗,那么將被廢棄。

            trace: 如果為true,那么每個被執(zhí)行的SQL語句將會在執(zhí)行期被log記錄(DEBUG LEVEL).你也可以注冊一個ConnectionListener (參看ProxoolFacade)得到這些信息.

            verbose: 詳細(xì)信息設(shè)置。 參數(shù) bool 值

          posted @ 2010-07-29 16:03 睫晉姬 閱讀(561) | 評論 (0)編輯 收藏

          Java中的LookAndFeel

            1、Metal風(fēng)格 (默認(rèn))

            String lookAndFeel = "javax.swing.plaf.metal.MetalLookAndFeel";

            UIManager.setLookAndFeel(lookAndFeel);

            2、Windows風(fēng)格

            String lookAndFeel = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel";

            UIManager.setLookAndFeel(lookAndFeel);

            3、Windows Classic風(fēng)格

            String lookAndFeel = "com.sun.java.swing.plaf.windows.WindowsClassicLookAndFeel";

            UIManager.setLookAndFeel(lookAndFeel);

            4、Motif風(fēng)格

            String lookAndFeel = "com.sun.java.swing.plaf.motif.MotifLookAndFeel";

            UIManager.setLookAndFeel(lookAndFeel);

            5、Mac風(fēng)格 (需要在相關(guān)的操作系統(tǒng)上方可實現(xiàn))

            String lookAndFeel = "com.sun.java.swing.plaf.mac.MacLookAndFeel";

            UIManager.setLookAndFeel(lookAndFeel);

            6、GTK風(fēng)格 (需要在相關(guān)的操作系統(tǒng)上方可實現(xiàn))

            String lookAndFeel = "com.sun.java.swing.plaf.gtk.GTKLookAndFeel";

            UIManager.setLookAndFeel(lookAndFeel);

            7、可跨平臺的默認(rèn)風(fēng)格

            String lookAndFeel = UIManager.getCrossPlatformLookAndFeelClassName();

            UIManager.setLookAndFeel(lookAndFeel);

            8、當(dāng)前系統(tǒng)的風(fēng)格

            String lookAndFeel = UIManager.getSystemLookAndFeelClassName();

            UIManager.setLookAndFeel(lookAndFeel);

            在Java中讓用戶能夠動態(tài)地更改應(yīng)用的外觀,可以給用戶更好地體驗,具體的實現(xiàn)方式是:

            1,先使用UIManager.setLookAndFeel(String s)方法設(shè)定對應(yīng)的外觀

            2,再使用SwingUtilities.updateComponentTreeUI(Component c)方法立刻更新應(yīng)用的外觀

            這兩個類均在javax.swing包中
          相關(guān)文章博客:睫晉姬 睫晉姬 睫晉姬 睫晉姬 睫晉姬 睫晉姬 睫晉姬 睫晉姬

          posted @ 2010-07-29 16:00 睫晉姬 閱讀(255) | 評論 (0)編輯 收藏

          Java多線程支持如何才能解決接口問題

            Java多線程支持需要我們不斷的進(jìn)行相關(guān)問題的解決,下面我們就來看看在接口問題上的相關(guān)問題解決方案,這樣才能更好的進(jìn)行不斷的干洗機(jī)創(chuàng)新和學(xué)習(xí)。希望大家有所了解。

            Java多線程支持,所有實現(xiàn)Runnable接口的類都可被啟動一個新線程,新線程會執(zhí)行該實例的run()方法,當(dāng)run()方法執(zhí)行完畢后,線程就結(jié)束了。一旦一個線程執(zhí)行完畢,這個實例就不能再重新啟動,只能重新生成一個新實例,再啟動一個新線程。

            Thread類是實現(xiàn)了Runnable接口的一個實例,它代表一個線程的實例,并且,啟動線程的唯一方法就是通過Thread類的start()實例方法:

            1.Thread t = new Thread();

            2.t.start();

            start()方法是一個native方法,它將啟動一個新線程,并執(zhí)行run()方法。Thread類默認(rèn)的run()方法什么也不做就退出了。注意:直接調(diào)用run()方法并不會啟動一個新線程,它和調(diào)用一個普通的java多線程支持方法沒有什么區(qū)別。

            因此,有兩個方法可以實現(xiàn)自己的線程:

            方法1:自己的類extend Thread,并復(fù)寫run()方法,就可以啟動新線程并執(zhí)行自己定義的run()方法。例如:

            3.public class MyThread extends Thread {

            4.public run() {

            5.System.out.println("MyThread.run()");

            6.}

            7.}

            在合適的地方啟動線程:new MyThread().start();

            方法2:如果自己的類已經(jīng)extends另一個類,就無法直接extends Thread,此時,必須實現(xiàn)一個Runnable接口:

            8.public class MyThread extends OtherClass implements Runnable {

            9.public run() {

            10.System.out.println("MyThread.run()");

            11.}

            12.}

            為了啟動MyThread,需要首先實例化一個Thread,并傳入自己的MyThread實例:

            13.MyThread myt = new MyThread();

            14.Thread t = new Thread(myt);

            15.t.start();

            事實上,當(dāng)傳入一個Runnable target參數(shù)給Thread后,Thread的run()方法就會調(diào)用target.run(),參考JDK源代碼:

            16.public void run() {

            17.if (target != null) {

            18.target.run();

            19.}

            20.}

            Java多線程支持還有一些Name, ThreadGroup, isDaemon等設(shè)置,由于和線程設(shè)計模式關(guān)聯(lián)很少,這里就不多說了。

          posted @ 2010-07-29 15:59 睫晉姬 閱讀(308) | 評論 (0)編輯 收藏

          多線程開發(fā)的捷徑:構(gòu)建Java并發(fā)模型框架

            Java多線程特性為構(gòu)建高性能的應(yīng)用提供了極大的方便,但是也帶來了不少的麻煩。線程間同步、數(shù)據(jù)一致性等煩瑣的問題需要細(xì)心的考慮,一不小心就會出現(xiàn)一些微妙的,難以調(diào)試的錯誤。

            另外,應(yīng)用邏輯和線程邏輯糾纏在一起,會導(dǎo)致程序的邏輯結(jié)構(gòu)混亂,難以復(fù)用和維護(hù)。本文試圖給出一個解決這個問題的方案,通過構(gòu)建一個并發(fā)模型框架(framework),使得開發(fā)多線程的應(yīng)用變得容易。

            基礎(chǔ)知識

            Java語言提供了對于線程很好的支持,實現(xiàn)方法小巧、優(yōu)雅。對于方法重入的保護(hù),信號量(semaphore)和臨界區(qū)(critical section)機(jī)制的實現(xiàn)都非常簡潔。可以很容易的實現(xiàn)多線程間的同步操作從而保護(hù)關(guān)鍵數(shù)據(jù)的一致性。這些特點使得Java成為面向?qū)ο笳Z言中對于多線程特性支持方面的佼佼者(C++正在試圖把boost庫中的對于線程的支持部分納入語言標(biāo)準(zhǔn))。

            Java中內(nèi)置了對于對象并發(fā)訪問的支持,每一個對象都有一個監(jiān)視器(monitor),同時只允許一個線程持有監(jiān)視器從而進(jìn)行對對象的訪問,那些沒有獲得監(jiān)視器的線程必須等待直到持有監(jiān)視器的線程釋放監(jiān)視器。對象通過synchronized關(guān)鍵字來聲明線程必須獲得監(jiān)視器才能進(jìn)行對自己的訪問。

            synchronized聲明僅僅對于一些較為簡單的線程間同步問題比較有效,對于哪些復(fù)雜的同步問題,比如帶有條件的同步問題,Java提供了另外的解決方法,wait/notify/notifyAll。

            獲得對象監(jiān)視器的線程可以通過調(diào)用該對象的wait方法主動釋放監(jiān)視器,等待在該對象的線程等待隊列上,此時其他線程可以得到中頻點焊機(jī)監(jiān)視器從而訪問該對象,之后可以通過調(diào)用notify/notifyAll方法來喚醒先前因調(diào)用wait方法而等待的線程。

            一般情況下,對于wait/notify/notifyAll方法的調(diào)用都是根據(jù)一定的條件來進(jìn)行的,比如:經(jīng)典的生產(chǎn)者/消費(fèi)者問題中對于隊列空、滿的判斷。熟悉POSIX的讀者會發(fā)現(xiàn),使用wait/notify/notifyAll可以很容易的實現(xiàn)POSIX中的一個線程間的高級同步技術(shù):條件變量。

            簡單例子

            本文將圍繞一個簡單的例子展開論述,這樣可以更容易突出我們解決問題的思路、方法。本文想向讀者展現(xiàn)的正是這些思路、方法。這些思路、方法更加適用于解決大規(guī)模、復(fù)雜應(yīng)用中的并發(fā)問題。考慮一個簡單的例子,我們有一個服務(wù)提供者,它通過一個接口對外提供服務(wù),服務(wù)內(nèi)容非常簡單,就是在標(biāo)準(zhǔn)輸出上打印Hello World。類結(jié)構(gòu)圖如下:

          類結(jié)構(gòu)圖

            代碼如下:

            1.interface Service

            2.{

            3.    public void sayHello();

            4.}

            5.class ServiceImp implements Service

            6.{

            7.    public void sayHello() {

            8.        System.out.println("Hello World!");

            9.    }

            10.}

            11.class Client

            12.{

            13.    public Client(Service s) {

            14.        _service = s;

            15.}

            16.    public void requestService() {

            17.        _service.sayHello();

            18.    }

            19.    private Service _service;

            20.}

            如果現(xiàn)在有新的需求,要求該服務(wù)必須支持Client的并發(fā)訪問。一種簡單的方法就是在ServicImp類中的每個方法前面加上synchronized聲明,來保證自己內(nèi)部數(shù)據(jù)的一致性(當(dāng)然對于本例來說,目前是沒有必要的,因為ServiceImp沒有需要保護(hù)的數(shù)據(jù),但是隨著需求的變化,以后可能會有的)。但是這樣做至少會存在以下幾個問題:

            1.現(xiàn)在要維護(hù)ServiceImp的兩個版本:多線程版本和單線程版本(有些地方,比如其他項目,可能沒有并發(fā)的問題),容易帶來點凸焊機(jī)同步更新和正確選擇版本的問題,給維護(hù)帶來麻煩。

            2.如果多個并發(fā)的Client頻繁調(diào)用該服務(wù),由于是直接同步調(diào)用,會造成Client阻塞,降低服務(wù)質(zhì)量。

            3.很難進(jìn)行一些靈活的控制,比如:根據(jù)Client的優(yōu)先級進(jìn)行排隊等等。

            4.這些問題對于大型的多線程應(yīng)用服務(wù)器尤為突出,對于一些簡單的應(yīng)用(如本文中的例子)可能根本不用考慮。本文正是要討論這些問題的解決方案,文中的簡單的例子只是提供了一個說明問題,展示思路、方法的平臺。

            5.如何才能較好的解決這些問題,有沒有一個可以重用的解決方案呢?讓我們先把這些問題放一放,先來談?wù)労涂蚣苡嘘P(guān)的一些問題。

            框架概述

            熟悉面向?qū)ο蟮淖x者一定知道面向?qū)ο蟮淖畲蟮膬?yōu)勢之一就是:軟件復(fù)用。通過復(fù)用,可以減少很多的工作量,提高軟件開發(fā)生產(chǎn)率。復(fù)用本身也是分層次的,代碼級的復(fù)用和設(shè)計架構(gòu)的復(fù)用。

            大家可能非常熟悉C語言中的一些標(biāo)準(zhǔn)庫,它們提供了一些通用的功能讓你的程序使用。但是這些標(biāo)準(zhǔn)庫并不能影響你的程序結(jié)構(gòu)和設(shè)計思路,僅僅是提供一些機(jī)能,幫助你的程序完成工作。它們使你不必重頭編寫一般性的通用功能(比如printf),它們強(qiáng)調(diào)的是程序代碼本身的復(fù)用性,而不是設(shè)計架構(gòu)的復(fù)用性。

            那么什么是框架呢?所謂框架,它不同于一般的標(biāo)準(zhǔn)庫,是指一組緊密關(guān)聯(lián)的(類)classes,強(qiáng)調(diào)彼此的配合以完成某種可以重復(fù)運(yùn)用的設(shè)計概念。這些類之間以特定的方式合作,彼此不可或缺。它們相當(dāng)程度的影響了你的程序的形貌。框架本身規(guī)劃了應(yīng)用程序的骨干,讓程序遵循一定的流程和動線,展現(xiàn)一定的風(fēng)貌和功能。這樣就使程序員不必費(fèi)力于通用性的功能的繁文縟節(jié),集中精力于專業(yè)領(lǐng)域。

            有一點必須要強(qiáng)調(diào),放之四海而皆準(zhǔn)的框架是不存在的,也是最沒有用處的。框架往往都是針對某個特定應(yīng)用領(lǐng)域的,是在對這個應(yīng)用領(lǐng)域進(jìn)行深刻理解的基礎(chǔ)上,抽象出該應(yīng)用的概念模型,在這些抽象的概念上搭建的一個模型,是一個有形無體的框架。不同的具體應(yīng)用根據(jù)自身的特點對框架中的抽象概念進(jìn)行實現(xiàn),從而賦予框架生命,完成應(yīng)用的功能。

            基于框架的應(yīng)用都有兩部分構(gòu)成:框架部分和特定應(yīng)用部分。要想達(dá)到框架復(fù)用的目標(biāo),必須要做到框架部分和特定應(yīng)用部分的隔離。使用面向?qū)ο蟮囊粋€強(qiáng)大功能:多態(tài),可以實現(xiàn)這一點。在框架中完成抽象概念之間的交互、關(guān)聯(lián),把具體的實現(xiàn)交給特定的應(yīng)用來完成。其中一般都會大量使用了Template Method設(shè)計模式。Java中的Collection Framework以及微軟的MFC都是框架方面很好的例子。有興趣的讀者可以自行研究。

           

            構(gòu)建框架

            如何構(gòu)建一個Java并發(fā)模型框架呢?讓我們先回到原來的問題,先來分析一下原因。造成要維護(hù)多線程和單線程兩個版本的原因是由于把應(yīng)用邏輯和并發(fā)邏輯混在一起,如果能夠做到把應(yīng)用邏輯和并發(fā)模型進(jìn)行很好的隔離,那么應(yīng)用邏輯本身就可以很好的被復(fù)用,而且也很容易把并發(fā)邏輯添加進(jìn)來而不會對應(yīng)用邏輯造成任何影響。造成Client阻塞,性能降低以及無法進(jìn)行額外的控制的原因是由于所有的服務(wù)調(diào)用都是同步的,解決方案很簡單,改為異步調(diào)用方式,把服務(wù)的調(diào)用和服務(wù)的執(zhí)行分離。

            首先來介紹一個概念,活動對象(Active Object)。所謂活動對象是相對于被動對象(passive object)而言的,被動對象的方法的調(diào)用和執(zhí)行都是在同一個線程中的,被動對象方法的調(diào)用是同步的、阻塞的,一般的對象都屬于被動對象;主動對象的方法的調(diào)用和執(zhí)行是分離的,主動對象有自己獨立的執(zhí)行線程,主動對象的上海保潔公司方法的調(diào)用是由其他線程發(fā)起的,但是方法是在自己的線程中執(zhí)行的,主動對象方法的調(diào)用是異步的,非阻塞的。

            本框架的核心就是使用主動對象來封裝并發(fā)邏輯,然后把Client的請求轉(zhuǎn)發(fā)給實際的服務(wù)提供者(應(yīng)用邏輯),這樣無論是Client還是實際的服務(wù)提供者都不用關(guān)心并發(fā)的存在,不用考慮并發(fā)所帶來的數(shù)據(jù)一致性問題。從而實現(xiàn)應(yīng)用邏輯和并發(fā)邏輯的隔離,服務(wù)調(diào)用和服務(wù)執(zhí)行的隔離。下面給出關(guān)鍵的實現(xiàn)細(xì)節(jié)。

            本框架有如下幾部分構(gòu)成:

            1.一個ActiveObject類,從Thread繼承,封裝了并發(fā)邏輯的活動對象;

            2.一個ActiveQueue類,主要用來存放調(diào)用者請求;

            3.一個MethodRequest接口,主要用來封裝調(diào)用者的請求,Command設(shè)計模式的一種實現(xiàn)方式。它們的一個簡單的實現(xiàn)如下:

            1. //MethodRequest接口定義

            2.  interface MethodRequest

            3.{

            4.    public void call();

            5.}

            6.//ActiveQueue定義,其實就是一個producer/consumer隊列

            7.    class ActiveQueue

            8.{

            9.      public ActiveQueue() {

            10.        _queue = new Stack();

            11.      }

            12.    public synchronized void enqueue(MethodRequest mr) {

            13.        while(_queue.size() > QUEUE_SIZE) {

            14.            try {

            15.                   wait();

            16.            }catch (InterruptedException e) {

            17.                   e.printStackTrace();

            18.            }

            19.        }

            20.

            21.        _queue.push(mr);

            22.        notifyAll();

            23.        System.out.println("Leave Queue");

            24.    }

            25.    public synchronized MethodRequest dequeue() {

            26.        MethodRequest mr;

            27.

            28.        while(_queue.empty()) {

            29.            try {

            30.                wait();

            31.            }catch (InterruptedException e) {

            32.                e.printStackTrace();

            33.            }

            34.        }

            35.        mr = (MethodRequest)_queue.pop();

            36.        notifyAll();

            37.

            38. return mr;

            39.    }

            40.    private Stack _queue;

            41.    private final static int QUEUE_SIZE = 20;

            42.}

            43.//ActiveObject的定義

            44.class ActiveObject extends Thread

            45.{

            46.    public ActiveObject() {

            47.        _queue = new ActiveQueue();

            48.        start();

            49.    }

            50.    public void enqueue(MethodRequest mr) {

            51.        _queue.enqueue(mr);

            52.    }

            53.    public void run() {

            54.        while(true) {

            55.            MethodRequest mr = _queue.dequeue();

            56.            mr.call();

            57.        }

            58.    }

            59.    private ActiveQueue _queue;

            60.}

            通過上面的代碼可以看出正是這些類相互合作完成了對并發(fā)邏輯的封裝。開發(fā)者只需要根據(jù)需要實現(xiàn)MethodRequest接口,另外再定義一個服務(wù)代理類提供給使用者,在服務(wù)代理者類中把服務(wù)調(diào)用者的請求轉(zhuǎn)化為MethodRequest實現(xiàn),交給活動對象即可。

            使用該框架,可以較好的做到應(yīng)用邏輯和并發(fā)模型的分離,從而使開發(fā)者集中精力于應(yīng)用領(lǐng)域,然后平滑的和并發(fā)模型結(jié)合起來,并且可以針對ActiveQueue定制排隊機(jī)制,比如基于優(yōu)先級等。

           

            基于框架的解決方案

            本小節(jié)將使用上述的框架重新實現(xiàn)前面的例子,提供對于并發(fā)的支持。第一步先完成對于MethodRequest的實現(xiàn),對于我們的例子來說實現(xiàn)如下:

            1.class SayHello implements MethodRequest

            2.{

            3.    public SayHello(Service s) {

            4.        _service = s;

            5.    }

            6.    public void call() {

            7.        _service.sayHello();

            8.    }

            9.    private Service _service;

            10.}

            該類完成了對于服務(wù)提供接口sayHello方法的封裝。接下來定義一個服務(wù)代理類,來完成請求的封裝、排隊功能,當(dāng)然為了做到對Client透明,該類必須實現(xiàn)Service接口。定義如下:

            11.class ServiceProxy implements Service

            12.{

            13.    public ServiceProxy() {

            14.        _service = new ServiceImp();

            15.        _active_object = new ActiveObject();

            16.    }

            17.

            18.    public void sayHello() {

            19.        MethodRequest mr = new SayHello(_service);

            20.        _active_object.enqueue(mr);

            21.    }

            22.    private Service _service;

            23.    private ActiveObject _active_object;

            24.}

            其他的類和接口定義不變,下面對比一下并發(fā)邏輯增加前后的服務(wù)調(diào)用的變化,并發(fā)邏輯增加前,對于sayHello服務(wù)的調(diào)用方法:

            25.Service s = new ServiceImp();

            26.Client c = new Client(s);

            27.c.requestService();

            并發(fā)邏輯增加后,對于sayHello服務(wù)的調(diào)用方法:

            28.Service s = new  ServiceProxy();

            29.Client c = new Client(s);

            30.c.requestService();

            可以看出并發(fā)邏輯增加前后對于Client的ServiceImp都無需作任何改變,使用方式也非常一致,ServiceImp也能夠獨立的進(jìn)行重用。類結(jié)構(gòu)圖如下:

          類結(jié)構(gòu)圖

            讀者容易看出,使用框架也增加了一些復(fù)雜性,對于一些簡單的應(yīng)用來說可能根本就沒有必要使用本框架。希望讀者能夠根據(jù)自己的實際情況進(jìn)行判斷。

            結(jié)論

            本文圍繞一個簡單的例子論述了如何構(gòu)架一個Java并發(fā)模型框架,其中使用了一些構(gòu)建框架的常用技術(shù),當(dāng)然所構(gòu)建的框架和一些成熟的商用框架相比,顯得非常稚嫩,比如沒有考慮服務(wù)調(diào)用有返回值的情況,但是其思想方法是一致的,希望讀者能夠深加領(lǐng)會,這樣無論對于構(gòu)建自己的框架還是理解一些其他的框架都是很有幫助的。讀者可以對本文中的框架進(jìn)行擴(kuò)充,直接應(yīng)用到自己的工作中。

            優(yōu)點:

            1.增強(qiáng)了應(yīng)用的并發(fā)性,簡化了同步控制的復(fù)雜性;

            2.服務(wù)的請求和服務(wù)的執(zhí)行分離,使得可以對服務(wù)請求排隊,進(jìn)行靈活的控制;

            3.應(yīng)用邏輯和并發(fā)模型分離,使得程序結(jié)構(gòu)清晰,易于維護(hù)、重用;

            4.可以使開發(fā)者集中精力于應(yīng)用領(lǐng)域。

            缺點:

            1.由于框架所需類的存在,在一定程度上增加了程序的復(fù)雜性;

            2.如果應(yīng)用需要過多的活動對象,由于線程切換開銷會造成性能下降;

            3.可能會造成調(diào)試?yán)щy。

          posted @ 2010-07-29 15:55 睫晉姬 閱讀(268) | 評論 (0)編輯 收藏

          Java多線程程序設(shè)計初步

            在Java語言產(chǎn)生前,傳統(tǒng)的程序設(shè)計語言的程序同一時刻只能單任務(wù)操作,效率非常低,例如程序往往在接收數(shù)據(jù)輸入時發(fā)生阻塞,只有等到程序獲得數(shù)據(jù)后才能繼續(xù)運(yùn)行。隨著Internet的迅猛發(fā)展,這種狀況越來越不能讓人們?nèi)淌埽喝绻W(wǎng)絡(luò)接收熱合機(jī)數(shù)據(jù)阻塞,后臺程序就處于等待狀態(tài)而不繼續(xù)任何操作,而這種阻塞是經(jīng)常會碰到的,此時CPU資源被白白的閑置起來。如果在后臺程序中能夠同時處理多個任務(wù),該多好啊!應(yīng)Internet技術(shù)而生的Java語言解決了這個問題,多線程程序是Java語言的一個很重要的特點。在一個Java程序中,我們可以同時并行運(yùn)行多個相對獨立的線程,例如,我們?nèi)绻麆?chuàng)建一個線程來進(jìn)行數(shù)據(jù)輸入輸出,而創(chuàng)建另一個線程在后臺進(jìn)行其它的數(shù)據(jù)處理,如果輸入輸出線程在接收數(shù)據(jù)時阻塞,而處理數(shù)據(jù)的線程仍然在運(yùn)行。多線程程序設(shè)計大大提高了程序執(zhí)行效率和處理能力。

             線程的創(chuàng)建

            我們知道Java是面向?qū)ο蟮某绦蛘Z言,用Java進(jìn)行程序設(shè)計就是設(shè)計和使用類,Java為我們提供了線程類Thread來創(chuàng)建線程,創(chuàng)建線程與創(chuàng)建普通的類的對象的操作是一樣的,而線程就是Thread類或其子類的實例對象。下面是一個創(chuàng)建啟動一個線程的語句:

            Thread thread1=new Thread(); file://聲明一個對象實例,即創(chuàng)建一個線程;

            Thread1.run(); file://用Thread類中的run()方法啟動線程;

            從這個例子,我們可以通過Thread()構(gòu)造方法創(chuàng)建一個線程,并啟動該線程。事實上,啟動線程,也就是啟動線程的run()方法,而Thread類中的run()方法沒有任何操作語句,所以這個線程沒有任何操作。要使線程實現(xiàn)預(yù)定功能,必須定義自己的run()方法。Java中通常有兩種方式定義 run()方法:

            通過定義一個Thread類的子類,在該子類中重寫run()方法。Thread子類的實例對象就是一個線程,顯然,該線程有我們自己設(shè)計的線程體run()方法,啟動線程就啟動了子類中重寫的run()方法。

            通過Runnable接口,在該接口中定義run()方法的接口。所謂接口跟類非常類似,主要用來實現(xiàn)特殊功能,如復(fù)雜關(guān)系的多重繼承功能。在此,我們定義一個實現(xiàn)Runnable() 接口的類,在該類中定義自己的run()方法,然后以該類的實例對象為參數(shù)調(diào)用Thread類的構(gòu)造方法來創(chuàng)建一個線程。

            線程被實際創(chuàng)建后處于待命狀態(tài),激活(啟動)線程就是啟動線程的run()方法,這是通過調(diào)用線程的start()方法來實現(xiàn)的。

            下面一個例子實踐了如何通過上述兩種方法創(chuàng)建線程并啟動它們:

            // 通過Thread類的子類創(chuàng)建的線程;

              { file://自定義線程的run()方法;

             file://通過Runnable接口創(chuàng)建的另外一個線程;

             { file://自定義線程的run()方法;

             file://程序的主類'

             class Multi_Thread file://聲明主類;
               plubic static void mail(String args[]) file://聲明主方法;

                 thread1 threadone=new thread1(); file://用Thread類的子類創(chuàng)建線程;

                 Thread threadtwo=new Thread(new thread2()); file://用Runnable接口類的對象創(chuàng)建線程;

                 threadone.start(); threadtwo.start(); file://strat()方法啟動線程;


            運(yùn)行該程序就可以看出,線程threadone和threadtwo交替占用CPU,處于并行運(yùn)行狀態(tài)。可以看出,啟動線程的run()方法是通過調(diào)用線程的start()方法來實現(xiàn)的(見上例中主類),調(diào)用start()方法啟動線程的run()方法不同于一般的調(diào)用方法,調(diào)用一般方法時,必須等到一般方法執(zhí)行完畢才能夠返回start()方法,而啟動線程的run()方法后,start()告訴系統(tǒng)該線程準(zhǔn)備就緒可以啟動run()方法后,就返回 start()方法執(zhí)行調(diào)用start()方法語句下面的語句,這時run()方法可能還在運(yùn)行,這樣,線程的啟動和運(yùn)行并行進(jìn)行,實現(xiàn)了多任務(wù)操作。

            線程的優(yōu)先級

            對于多線程程序,每個線程的重要程度是不盡相同,如多個線程在等待獲得CPU時間時,往往我們需要優(yōu)先級高的線程優(yōu)先搶占到CPU時間得以執(zhí)行;又如多個線程交替執(zhí)行時,優(yōu)先級決定了級別高的線程得到CPU的次數(shù)多一些且時間多長一些;這樣,高優(yōu)先級的線程處理的任務(wù)效率就高一些。

            Java中線程的優(yōu)先級從低到高以整數(shù)1~10表示,共分為10級,設(shè)置優(yōu)先級是通過調(diào)用線程對象的setPriority()方法,如上例中,設(shè)置優(yōu)先級的語句為:

            thread1 threadone=new thread1(); file://用Thread類的子類創(chuàng)建線程;

            Thread threadtwo=new Thread(new thread2()); file://用Runnable接口類的對象創(chuàng)建線程;

            threadone.setPriority(6); file://設(shè)置threadone的優(yōu)先級6;

            threadtwo.setPriority(3); file://設(shè)置threadtwo的優(yōu)先級3;

            threadone.start(); threadtwo.start(); file://strat()方法啟動線程;

            這樣,線程threadone將會優(yōu)先于線程threadtwo執(zhí)行,并將占有更多的CPU時間。該例中,優(yōu)先級設(shè)置放在線程啟動前,也可以在啟動后進(jìn)行設(shè)置,以滿足不同的優(yōu)先級需求。
           線程的(同步)控制

            一個Java程序的多線程之間可以共享數(shù)據(jù)。當(dāng)線程以異步方式訪問共享數(shù)據(jù)時,有時候是不安全的或者不和邏輯的。比如,同一時刻一個線程在讀取數(shù)據(jù),另外一個線程在處理數(shù)據(jù),當(dāng)處理數(shù)據(jù)的線程沒有等到讀取收縮機(jī)數(shù)據(jù)的線程讀取完畢就去處理數(shù)據(jù),必然得到錯誤的處理結(jié)果。這和我們前面提到的讀取數(shù)據(jù)和處理數(shù)據(jù)并行多任務(wù)并不矛盾,這兒指的是處理數(shù)據(jù)的線程不能處理當(dāng)前還沒有讀取結(jié)束的數(shù)據(jù),但是可以處理其它的數(shù)據(jù)。

            如果我們采用多線程同步控制機(jī)制,等到第一個線程讀取完數(shù)據(jù),第二個線程才能處理該數(shù)據(jù),就會避免錯誤。可見,線程同步是多線程編程的一個相當(dāng)重要的技術(shù)。

            在講線程的同步控制前我們需要交代如下概念:

            1 用Java關(guān)鍵字synchonized同步對共享數(shù)據(jù)操作的方法

            在一個對象中,用synchonized聲明的方法為同步方法。Java中有一個同步模型-監(jiān)視器,負(fù)責(zé)管理線程對對象中的同步方法的訪問,它的原理是:賦予該對象唯一一把'鑰匙',當(dāng)多個線程進(jìn)入對象,只有取得該對象鑰匙的線程才可以訪問同步方法,其它線程在該對象中等待,直到該線程用wait() 方法放棄這把鑰匙,其它等待的線程搶占該鑰匙,搶占到鑰匙的線程后才可得以執(zhí)行,而沒有取得鑰匙的線程仍被阻塞在該對象中等待。

            file://聲明同步的一種方式:將方法聲明同步

            class store

            public synchonized void store_in()

            public synchonized void store_out(){

            2 利用wait()、notify()及notifyAll()方法發(fā)送消息實現(xiàn)線程間的相互聯(lián)系

            Java程序中多個線程通過消息來實現(xiàn)互動聯(lián)系的,這幾種方法實現(xiàn)了線程間的消息發(fā)送。例如定義一個對象的synchonized 方法,同一時刻只能夠有一個線程訪問該對象中的同步方法,其它線程被阻塞。通常可以用notify()或notifyAll()方法喚醒其它一個或所有線程。而使用wait()方法來使該線程處于阻塞狀態(tài),等待其它的線程用notify()喚醒。

            一個實際的例子就是生產(chǎn)和銷售,生產(chǎn)單元將產(chǎn)品生產(chǎn)出來放在倉庫中,銷售單元則從倉庫中提走產(chǎn)品,在這個過程中,銷售單元必須在倉庫中有產(chǎn)品時才能提貨;如果倉庫中沒有產(chǎn)品,則銷售單元必須等待。

            程序中,假如我們定義一個倉庫類store,該類的實例對象就相當(dāng)于倉庫,在store類中定義兩個成員方法:store_in(),用來模擬產(chǎn)品制造者往倉庫中添加產(chǎn)品;strore_out()方法則用來模擬銷售者從倉庫中取走產(chǎn)品。然后定義兩個線程類:customer類,其中的run()方法通過調(diào)用倉庫類中的store_out()從倉庫中取走產(chǎn)品,模擬銷售者;另外一個線程類producer中的run()方法通過調(diào)用倉庫類中的 store_in()方法向倉庫添加產(chǎn)品,模擬產(chǎn)品制造者。在主類中創(chuàng)建并啟動線程,實現(xiàn)向倉庫中添加產(chǎn)品或取走產(chǎn)品。

            如果倉庫類中的store_in() 和store_out()方法不聲明同步,這就是個一般的多線程,我們知道,一個程序中的多線程是交替執(zhí)行的,運(yùn)行也是無序的,這樣,就可能存在這樣的問題:

            倉庫中沒有產(chǎn)品了,銷售者還在不斷光顧,而且還不停的在'取'產(chǎn)品,這在現(xiàn)實中是不可思義的,在程序中就表現(xiàn)為負(fù)值;如果將倉庫類中的stroe_in ()和store_out()方法聲明同步,如上例所示:就控制了同一時刻只能有一個線程訪問倉庫對象中的同步方法;即一個生產(chǎn)類線程訪問被聲明為同步的 store_in()方法時,其它線程將不能夠訪問對象中的store_out()同步方法,當(dāng)然也不能訪問store_in()方法。必須等到該線程調(diào)用wait()方法放棄鑰匙,其它線程才有機(jī)會訪問同步方法。

          posted @ 2010-07-29 15:50 睫晉姬 閱讀(212) | 評論 (0)編輯 收藏

          Java List遍歷方法及其效率對比

            Java代碼

            1.package com.zbalpha.test;

            2.

            3.import java.util.ArrayList;

            4.import java.util.Iterator;

            5.import java.util.List;

            6.

            7.public class ListTest {

            8.    public static void main(String args[]){

            9.        List<Long> lists = new ArrayList<Long>();

            10.

            11.        for(Long i=0l;i<1000000l;i++){

            12.            lists.add(i);

            13.        }

            14.

            15.        Long oneOk = oneMethod(lists);

            16.        Long twoOk = twoMethod(lists);

            17.        Long threeOk = threeMethod(lists);

            18.        Long fourOk = fourMethod(lists);

            19.

            20.        System.out.println("One:" + oneOk);

            21.        System.out.println("Two:" + twoOk);

            22.        System.out.println("Three:" + threeOk);

            23.        System.out.println("four:" + fourOk);

            24.

            25.    }

            26.

            27.    public static Long oneMethod(List<Long> lists){

            28.

            29.        Long timeStart = System.currentTimeMillis();

            30.        for(int i=0;i<lists.size();i++)    {

            31.            System.out.println(lists.get(i));

            32.        }

            33.        Long timeStop = System.currentTimeMillis();

            34.

            35.        return timeStop -timeStart ;

            36.    }

            37.

            38.    public static Long twoMethod(List<Long> lists){

            39.

            40.        Long timeStart = System.currentTimeMillis();

            41.        for(Long string : lists)    {

            42.            System.out.println(string);

            43.        }

            44.        Long timeStop = System.currentTimeMillis();

            45.

            46.        return timeStop -timeStart ;

            47.    }

            48.

            49.    public static Long threeMethod(List<Long> lists){

            50.

            51.        Long timeStart = System.currentTimeMillis();

            52.        Iterator<Long> it = lists.iterator();

            53.        while (it.hasNext())

            54.        {

            55.                System.out.println(it.next());

            56.        }

            57.        Long timeStop = System.currentTimeMillis();

            58.

            59.        return timeStop -timeStart ;

            60.    }

            61.

            62.

            63.

            64.    public static Long fourMethod(List<Long> lists){

            65.

            66.        Long timeStart = System.currentTimeMillis();

            67.        for(Iterator<Long> i = lists.iterator(); i.hasNext();)    {

            68.            System.out.println(i.next());

            69.        }

            70.        Long timeStop = System.currentTimeMillis();

            71.

            72.        return timeStop -timeStart ;

            73.    }

            74.}

            容器類可以大大提高編程效率和編程能力,在Java2中,所有的容器都由SUN公司的Joshua Bloch進(jìn)行了重新設(shè)計,豐富了容器類庫的功能。

            Java2容器類類庫的用途是“保存對象”,它分為兩類:

            Collection----一組獨立的元素,通常這些元素都服從某種規(guī)則。List必須保持元素特定的順序,而Set不能有重復(fù)元素。

            Map----一組成對的“鍵值對”對象,即其元素是成對的對象,最典型的應(yīng)用就是數(shù)據(jù)字典,并且還有其它廣泛的應(yīng)用。另外,Map可以返回其所有鍵豐胸組成的Set和其所有值組成的Collection,或其鍵值對組成的Set,并且還可以像數(shù)組一樣擴(kuò)展多維Map,只要讓Map中鍵值對的每個 “值”是一個Map即可。

            1.迭代器

            迭代器是一種設(shè)計模式,它是一個對象,它可以遍歷并選擇序列中的對象,而開發(fā)人員不需要了解該序列的底層結(jié)構(gòu)。迭代器通常被稱為“輕量級”對象,因為創(chuàng)建它的代價小。

            Java中的Iterator功能比較簡單,并且只能單向移動:

            (1) 使用方法iterator()要求容器返回一個Iterator。第一次調(diào)用Iterator的next()方法時,它返回序列的第一個元素。

            (2) 使用next()獲得序列中的下一個元素。

            (3) 使用hasNext()檢查序列中是否還有元素。

            (4) 使用remove()將迭代器新返回的元素刪除。

            Iterator是Java迭代器最簡單的實現(xiàn),為List設(shè)計的ListIterator具有更多的功能,它可以從兩個方向遍歷List,也可以從List中插入和刪除元素。

            2.List的功能方法

            List(interface): 次序是List最重要的特點;它確保維護(hù)元素特定的順序。List為Collection添加了許多方法,使得能夠向List中間插入與移除元素(只推薦 LinkedList使用)。一個List可以生成ListIterator,使用它可以從兩個方向遍歷List,也可以從List中間插入和刪除元素。

            ArrayList: 由數(shù)組實現(xiàn)的List。它允許對元素進(jìn)行快速隨機(jī)訪問,但是向List中間插入與移除元素的速度很慢。ListIterator只應(yīng)該用來由后向前遍歷ArrayList,而不是用來插入和刪除元素,因為這比LinkedList開銷要大很多。

            LinkedList: 對順序訪問進(jìn)行了優(yōu)化,向List中間插入與刪除得開銷不大,隨機(jī)訪問則相對較慢(可用ArrayList代替)。它具有方法addFirst()、 addLast()、getFirst()、getLast()、removeFirst()、removeLast(),這些方法(沒有在任何接口或基類中定義過)使得LinkedList可以當(dāng)作堆棧、隊列和雙向隊列使用。

            3.Set的功能方法

            Set(interface): 存入Set的每個元素必須是唯一的,因為Set不保存重復(fù)元素。加入Set的Object必須定義equals()方法以確保對象的唯一性。Set與Collection有完全一樣的接口。Set接口不保證維護(hù)元素的次序。

            HashSet: 為快速查找而設(shè)計的Set。存入HashSet的對象必須定義hashCode()。

            TreeSet: 保持次序的Set,底層為樹結(jié)構(gòu)。使用它可以從Set中提取有序的序列。

            LinkedHashSet: 具有HashSet的查詢速度,且內(nèi)部使用鏈表維護(hù)元素的順序(插入的次序)。于是在使用迭代器遍歷Set時,結(jié)果會按元素插入的次序顯示。

            HashSet采用散列函數(shù)對元素進(jìn)行排序,這是專門為快速查詢而設(shè)計的;TreeSet采用紅黑樹的數(shù)據(jù)結(jié)構(gòu)進(jìn)行排序元素;LinkedHashSet內(nèi)部使用散列以加快查詢速度,同時使用鏈表維護(hù)元素的次序,使得看起來元素是以插入的順序保存的。需要注意的是,生成自己的類時,Set需要維護(hù)元素的存儲順序,因此要實現(xiàn)Comparable接口并定義compareTo()方法。

          posted @ 2010-07-29 15:37 睫晉姬 閱讀(11919) | 評論 (1)編輯 收藏

          Java中synchronized用法

            在java編程思想中對synchronized的一點解釋:

            1、synchronized關(guān)鍵字的作用域有二種:

            1)是某個對象實例內(nèi),synchronized aMethod(){}可以防止多個線程同時訪問這個對象的synchronized方法(如果一個對象有多個synchronized方法,只要一個線程訪問了其中的一個synchronized方法,其它線程不能同時訪問這個對象中任何一個synchronized方法)。這時,不同的對象實例的synchronized方法是不相干擾的。也就是說,其它線程照樣可以同時訪問相同類的另一個對象實例中的synchronized方法;

            2)是某個類的范圍,synchronized static aStaticMethod{}防止多個線程同時訪問這個類中的synchronized static 方法。它可以對類的所有對象實例起作用。

            2、除了方法前用synchronized關(guān)鍵字,synchronized關(guān)鍵字還可以用于方法中的某個區(qū)塊中,表示只對這個區(qū)塊的資源實行互斥訪問。用法是: synchronized(this){/*區(qū)塊*/},它的作用域是當(dāng)前對象;

            3、synchronized關(guān)鍵字是不能繼承的,也就是說,基類的方法synchronized f(){} 在繼承類中并不自動是synchronized f(){},而是變成了f(){}。繼承類需要你顯式的指定它的某個方法為synchronized方法;

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

            java里面synchronized用法

            synchronized的一個簡單例子

            public class TextThread

            {

            /**

            * @param args

            */

            public static void main(String[] args)

            {

            // TODO 自動生成方法存根

            TxtThread tt = new TxtThread();

            new Thread(tt).start();

            new Thread(tt).start();

            new Thread(tt).start();

            new Thread(tt).start();

            }

            }

            class TxtThread implements Runnable

            {

            int num = 100;

            String str = new String();

            public void run()

            {

            while (true)

            {

            synchronized(str)

            {

            if (num>0)

            {

            try

            {

            Thread.sleep(10);

            }

            catch(Exception e)

            {

            e.getMessage();

            }

            System.out.println(Thread.currentThread().getName()+ "this is "+ num--);

            }

            }

            }

            }

            }

            上面的例子中為了制造一個時間差,也就是出錯的機(jī)會,使用了Thread.sleep(10)

            Java對多線程的支持與衛(wèi)星電視同步機(jī)制深受大家的喜愛,似乎看起來使用了synchronized關(guān)鍵字就可以輕松地解決多線程共享數(shù)據(jù)同步問題。到底如何?――還得對synchronized關(guān)鍵字的作用進(jìn)行深入了解才可定論。

            總的說來,synchronized關(guān)鍵字可以作為函數(shù)的修飾符,也可作為函數(shù)內(nèi)的語句,也就是平時說的同步方法和同步語句塊。如果再細(xì)的分類,synchronized可作用于instance變量、object reference(對象引用)、static函數(shù)和class literals(類名稱字面常量)身上。

            在進(jìn)一步闡述之前,我們需要明確幾點:

            A.無論synchronized關(guān)鍵字加在方法上還是對象上,它取得的鎖都是對象,而不是把一段代碼或函數(shù)當(dāng)作鎖――而且同步方法很可能還會被其他線程的對象訪問。

            B.每個對象只有一個鎖(lock)與之相關(guān)聯(lián)。

            C.實現(xiàn)同步是要很大的系統(tǒng)開銷作為代價的,甚至可能造成死鎖,所以盡量避免無謂的同步控制。

            接著來討論synchronized用到不同地方對代碼產(chǎn)生的影響:

            假設(shè)P1、P2是同一個類的不同對象,這個類中定義了以下幾種情況的同步塊或同步方法,P1、P2就都可以調(diào)用它們。

            1.  把synchronized當(dāng)作函數(shù)修飾符時,示例代碼如下:

            Public synchronized void methodAAA()

            {

            //….

            }

            這也就是同步方法,那這時synchronized鎖定的是哪個對象呢?它鎖定的是調(diào)用這個同步方法對象。也就是說,當(dāng)一個對象P1在不同的線程中執(zhí)行這個同步方法時,它們之間會形成互斥,達(dá)到同步的效果。但是這個對象所屬的Class所產(chǎn)生的另一對象P2卻可以任意調(diào)用這個被加了synchronized關(guān)鍵字的方法。

            上邊的示例代碼等同于如下代碼:

            public void methodAAA()

            {

            synchronized (this)      //  (1)

            {

            //…..

            }

            }

            (1)處的this指的是什么呢?它指的就是調(diào)用這個方法的對象,如P1。可見同步方法實質(zhì)是將synchronized作用于object reference。――那個拿到了P1對象鎖的線程,才可以調(diào)用P1的同步方法,而對P2而言,P1這個鎖與它毫不相干,程序也可能在這種情形下擺脫同步機(jī)制的控制,造成數(shù)據(jù)混亂:(

            2.同步塊,示例代碼如下:

            public void method3(SomeObject so)

            {

            synchronized(so)

            {

            //…..

            }

            }

            這時,鎖就是so這個對象,誰拿到這個鎖誰就可以運(yùn)行它所控制的那段代碼。當(dāng)有一個明確的對象作為鎖時,就可以這樣寫程序,但當(dāng)沒有明確的對象作為鎖,只是想讓一段代碼同步時,可以創(chuàng)建一個特殊的instance變量(它得是一個對象)來充當(dāng)鎖:

            class Foo implements Runnable

            {

            private byte[] lock = new byte[0];  // 特殊的instance變量

            Public void methodA()

            {

            synchronized(lock) { //… }

            }

            //…..

            }

            注:零長度的byte數(shù)組對象創(chuàng)建起來將比任何對象都經(jīng)濟(jì)――查看編譯后的字節(jié)碼:生成零長度的byte[]對象只需3條操作碼,而Object lock = new Object()則需要7行操作碼。

            3.將synchronized作用于static 函數(shù),示例代碼如下:

            Class Foo

            {

            public synchronized static void methodAAA()   // 同步的static 函數(shù)

            {

            //….

            }

            public void methodBBB()

            {

            synchronized(Foo.class)   //  class literal(類名稱字面常量)

            }

            }

            代碼中的methodBBB()方法是把class literal作為鎖的情況,它和同步的static函數(shù)產(chǎn)生的效果是一樣的,取得的鎖很特別,是當(dāng)前調(diào)用這個方法的衛(wèi)星電視對象所屬的類(Class,而不再是由這個Class產(chǎn)生的某個具體對象了)。

            記得在《Effective Java》一書中看到過將 Foo.class和 P1.getClass()用于作同步鎖還不一樣,不能用P1.getClass()來達(dá)到鎖這個Class的目的。P1指的是由Foo類產(chǎn)生的對象。

            可以推斷:如果一個類中定義了一個synchronized的static函數(shù)A,也定義了一個synchronized 的instance函數(shù)B,那么這個類的同一對象Obj在多線程中分別訪問A和B兩個方法時,不會構(gòu)成同步,因為它們的鎖都不一樣。A方法的鎖是Obj這個對象,而B的鎖是Obj所屬的那個Class。

            小結(jié)如下:

            搞清楚synchronized鎖定的是哪個對象,就能幫助我們設(shè)計更安全的多線程程序。

            還有一些技巧可以讓我們對共享資源的同步訪問更加安全:

            1.  定義private 的instance變量+它的 get方法,而不要定義public/protected的instance變量。如果將變量定義為public,對象在外界可以繞過同步方法的控制而直接取得它,并改動它。這也是JavaBean的標(biāo)準(zhǔn)實現(xiàn)方式之一。

            2.  如果instance變量是一個對象,如數(shù)組或ArrayList什么的,那上述方法仍然不安全,因為當(dāng)外界對象通過get方法拿到這個instance對象的引用后,又將其指向另一個對象,那么這個private變量也就變了,豈不是很危險。 這個時候就需要將get方法也加上synchronized同步,并且,只返回這個private對象的clone()――這樣,調(diào)用端得到的就是對象副本的引用了。

          posted @ 2010-07-29 15:31 睫晉姬 閱讀(208) | 評論 (0)編輯 收藏

          JDK 5.0中的泛型類型學(xué)習(xí)

            JDK 5.0 中增加的泛型類型,是 Java 語言中類型安全的一次重要改進(jìn)。但是,對于初次使用泛型類型的用戶來說,泛型的某些方面看起來可能不容易明白,甚至非常奇怪。在本月的“Java 理論和實踐”中,Brian Goetz 分析了束縛第一次使用泛型的用戶的常見陷阱。您可以通過討論論壇與作者和其他讀者分享您對本文的看法。(也可以單擊本文頂端或底端的討論來訪問這個論壇。)

            表面上看起來,無論語法還是應(yīng)用的環(huán)境(比如容器類),泛型類型(或者泛型)都類似于 C++ 中的模板。但是這種相似性僅限于表面,Java 語言中的泛型基本上完全在編譯器中實現(xiàn),由編譯器執(zhí)行類型檢查和類型推斷,然后生成普通的非泛型的字節(jié)碼。這種實現(xiàn)技術(shù)稱為擦除(erasure)(編譯器使用泛型類型信息保證類型安全,然后在生成字節(jié)碼之前將其清除),這項技術(shù)有一些奇怪,并且有時會帶來一些令人迷惑的后果。雖然范型是 Java 類走向類型安全的一大步,但是在學(xué)習(xí)使用泛型的過程中幾乎肯定會遇到頭痛(有時候讓人無法忍受)的問題。

            注意:本文假設(shè)您對 JDK 5.0 中的范型有基本的了解。

            泛型不是協(xié)變的

            雖然將集合看作是數(shù)組的抽象會有所幫助,但是數(shù)組還有一些集合不具備的特殊性質(zhì)。Java 語言中的數(shù)組是協(xié)變的(covariant),也就是說,如果 Integer 擴(kuò)展了 Number(事實也是如此),那么不僅 Integer 是 Number,而且 Integer[] 也是 Number[],在要求 Number[] 的地方完全可以傳遞或者賦予 Integer[]。(更正式地說,如果 Number 是 Integer 的超類型,那么 Number[] 也是 Integer[] 的超類型)。您也許認(rèn)為這一原理同樣適用于泛型類型 —— List<Number> 是 List<Integer> 的超類型,那么可以在需要 List<Number> 的地方傳遞 List<Integer>。不幸的是,情況并非如此。

            不允許這樣做有一個很充分的理由:這樣做將破壞要提供的類型安全泛型。如果能夠?qū)?List<Integer> 賦給 List<Number>。那么下面的代碼就允許將非 Integer 的內(nèi)容放入 List<Integer>:

            List<Integer> li = new ArrayList<Integer nike jordan 2010>();

            List<Number> ln = li; // illegal

            ln.add(new Float(3.1415));

            因為 ln 是 List<Number>,所以向其添加 Float 似乎是完全合法的。但是如果 ln 是 li 的別名,那么這就破壞了蘊(yùn)含在 li 定義中的類型安全承諾 —— 它是一個整數(shù)列表,這就是泛型類型不能協(xié)變的原因。

            其他的協(xié)變問題

            數(shù)組能夠協(xié)變而泛型不能協(xié)變的另一個后果是,不能實例化泛型類型的數(shù)組(new List<String>[3] 是不合法的),除非類型參數(shù)是一個未綁定的通配符(new List<?>[3] 是合法的)。讓我們看看如果允許聲明泛型類型數(shù)組會造成什么后果:

            List<String>[] lsa = new List<String>[10]; // illegal

            Object[] oa = lsa;  // OK because List<String> is a subtype of Object

            List<Integer> li = new ArrayList<Integer>();

            li.add(new Integer(3));

            oa[0] = li;

            String s = lsa[0].get(0);

            最后一行將拋出 ClassCastException,因為這樣將把 List<Integer> 填入本應(yīng)是 List<String> 的位置。因為數(shù)組協(xié)變會破壞泛型的類型安全,所以不允許實例化泛型類型的數(shù)組(除非類型參數(shù)是未綁定的通配符,比如 List<?>)。

            構(gòu)造延遲

            因為可以擦除功能,所以 List<Integer> 和 List<String> 是同一個類,編譯器在編譯 List<V> 時只生成一個類(和 C++ 不同)。因此,在編譯 List<V> 類時,編譯器不知道 V 所表示的類型,所以它就不能像知道類所表示的具體類型那樣處理 List<V> 類定義中的類型參數(shù)(List<V> 中的 V)。

            因為運(yùn)行時不能區(qū)分 List<String> 和 List<Integer>(運(yùn)行時都是 List),用泛型類型參數(shù)標(biāo)識類型的變量的構(gòu)造就成了問題。運(yùn)行時缺乏類型信息,這給泛型容器類和希望創(chuàng)建保護(hù)性副本的泛型類提出了難題。

            比如泛型類 Foo:

            class Foo<T> {

            public void doSomething(T param) { ... }

            }

            在這里可以看到一種模式 —— 與泛型有關(guān)的很多問題或者折衷并非來自泛型本身,而是保持和已有代碼兼容的要求帶來的副作用。

            泛化已有的類

            在轉(zhuǎn)化現(xiàn)有的庫類來使用泛型方面沒有多少技巧,但與平常的情況相同,向后兼容性不會憑空而來。我已經(jīng)討論了兩個例子,其中向后兼容性限制了類庫的泛化。

            另一種不同的泛化方法可能不存在向后兼容問題,這就是 Collections.toArray nike shox r4(Object[])。傳入 toArray() 的數(shù)組有兩個目的 —— 如果集合足夠小,那么可以將其內(nèi)容直接放在提供的數(shù)組中。否則,利用反射(reflection)創(chuàng)建相同類型的新數(shù)組來接受結(jié)果。如果從頭開始重寫 Collections 框架,那么很可能傳遞給 Collections.toArray() 的參數(shù)不是一個數(shù)組,而是一個類文字:

            interface Collection<E> {

            public T[] toArray(Class<T super E> elementClass);

            }

            因為 Collections 框架作為良好類設(shè)計的例子被廣泛效仿,但是它的設(shè)計受到向后兼容性約束,所以這些地方值得您注意,不要盲目效仿。

            首先,常常被混淆的泛型 Collections API 的一個重要方面是 containsAll()、removeAll() 和 retainAll() 的簽名。您可能認(rèn)為 remove() 和 removeAll() 的簽名應(yīng)該是:

            interface Collection<E> {

            public boolean remove(E e);  // not really

            public void removeAll(Collection<? extends E> c);  // not really

            }

            但實際上卻是:

            interface Collection<E> {

            public boolean remove(Object o);

            public void removeAll(Collection<?> c);

            }

            為什么呢?答案同樣是因為向后兼容性。x.remove(o) 的接口表明“如果 o 包含在 x 中,則刪除它,否則什么也不做。”如果 x 是一個泛型集合,那么 o 不一定與 x 的類型參數(shù)兼容。如果 removeAll() 被泛化為只有類型兼容時才能調(diào)用(Collection<? extends E>),那么在泛化之前,合法的代碼序列就會變得不合法,比如:

            // a collection of Integers

            Collection c = new HashSet();

            // a collection of Objects

            Collection r = new HashSet();

            c.removeAll(r);

            如果上述片段用直觀的方法泛化(將 c 設(shè)為 Collection<Integer>,r 設(shè)為 Collection<Object>),如果 removeAll() 的簽名要求其參數(shù)為 Collection<? extends E> 而不是 no-op,那么就無法編譯上面的代碼。泛型類庫的一個主要目標(biāo)就是不打破或者改變已有代碼的語義,因此,必須用比從頭重新設(shè)計泛型所使用類型約束更弱的類型約束來定義 remove()、removeAll()、retainAll() 和 containsAll()。

            在泛型之前設(shè)計的類可能阻礙了“顯然的”泛型化方法。這種情況下就要像上例這樣進(jìn)行折衷,但是如果從頭設(shè)計新的泛型類,理解 Java 類庫中的哪些東西是向后兼容的結(jié)果很有意義,這樣可以避免不適當(dāng)?shù)哪7隆?/p>

            擦除的實現(xiàn)

            因為泛型基本上都是在 Java 編譯器中而不是運(yùn)行庫中實現(xiàn)的,所以在生成字節(jié)碼的時候,差不多所有關(guān)于泛型類型的類型信息都被“擦掉”了。換句話說,編譯器生成的代碼與您手工編寫的不用泛型、檢查程序的類型安全后進(jìn)行強(qiáng)制類型轉(zhuǎn)換所得到的代碼基本相同。與 C++ 不同,List<Integer> 和 List<String> 是同一個類(雖然是不同的類型但都是 List<?> 的子類型,與以前的版本相比,在 JDK 5.0 中這是一個更重要的區(qū)別)。

            擦除意味著一個類不能同時實現(xiàn) Comparable<String> 和 Comparable<Number>,因為事實上兩者都在同一個接口中,指定同一個 compareTo() 方法。聲明 DecimalString 類以便與 String 與 Number 比較似乎是明智的,但對于 Java 編譯器來說,這相當(dāng)于對同一個方法進(jìn)行了兩次聲明:

            public class DecimalString implements Comparable fashion cap<Number>, Comparable<String> { ... } // nope

            擦除的另一個后果是,對泛型類型參數(shù)是用強(qiáng)制類型轉(zhuǎn)換或者 instanceof 毫無意義。下面的代碼完全不會改善代碼的類型安全性:

            public <T> T naiveCast(T t, Object o) { return (T) o; }

            編譯器僅僅發(fā)出一個類型未檢查轉(zhuǎn)換警告,因為它不知道這種轉(zhuǎn)換是否安全。naiveCast() 方法實際上根本不作任何轉(zhuǎn)換,T 直接被替換為 Object,與期望的相反,傳入的對象被強(qiáng)制轉(zhuǎn)換為 Object。

            擦除也是造成上述構(gòu)造問題的原因,即不能創(chuàng)建泛型類型的對象,因為編譯器不知道要調(diào)用什么構(gòu)造函數(shù)。如果泛型類需要構(gòu)造用泛型類型參數(shù)來指定類型的對象,那么構(gòu)造函數(shù)應(yīng)該接受類文字(Foo.class)并將它們保存起來,以便通過反射創(chuàng)建實例。

            結(jié)束語

            泛型是 Java 語言走向類型安全的一大步,但是泛型設(shè)施的設(shè)計和類庫的泛化并非未經(jīng)過妥協(xié)。擴(kuò)展虛擬機(jī)指令集來支持泛型被認(rèn)為是無法接受的,因為這會為 Java 廠商升級其 JVM 造成難以逾越的障礙。因此采用了可以完全在編譯器中實現(xiàn)的擦除方法。類似地,在泛型 Java 類庫時,保持向后兼容也為類庫的泛化方式設(shè)置了很多限制,產(chǎn)生了一些混亂的、令人沮喪的結(jié)構(gòu)(如 Array.newInstance())。這并非泛型本身的問題,而是與語言的演化與兼容有關(guān)。但這些也使得泛型學(xué)習(xí)和應(yīng)用起來更讓人迷惑,更加困難。

          posted @ 2010-07-29 15:23 睫晉姬 閱讀(219) | 評論 (0)編輯 收藏

          2009年12月5日 #

          JBoss Web和Tomcat的區(qū)別

            在Web2.0的浪潮中,各種頁面技術(shù)和框架不斷涌現(xiàn),為服務(wù)器端的基礎(chǔ)架構(gòu)提出了更高的穩(wěn)定性和可擴(kuò)展性的要求。近年來,作為開源中間件的全球領(lǐng)導(dǎo)者,JBoss在J2EE應(yīng)用服務(wù)器領(lǐng)域已成為發(fā)展最為迅速的應(yīng)用服務(wù)器。在市場占有率和服務(wù)滿意度上取得了巨大的成功,絲毫不遜色于其它的非開源競爭對手,如WebSphere、WebLogic、Application Server。JBoss Web的諸多優(yōu)越性能,正是其廣為流行的原因。

            基于Tomcat內(nèi)核,青勝于藍(lán)

            Tomcat 服務(wù)器是一個免費(fèi)的開放源代碼的Web 應(yīng)用服務(wù)器,技術(shù)先進(jìn)、性能穩(wěn)定,而且免費(fèi),因而深受Java 愛好者的喜愛并得到了部分軟件開發(fā)商的認(rèn)可。其運(yùn)行時占用的系統(tǒng)資源小,擴(kuò)展性好,且支持負(fù)載平衡與郵件服務(wù)等開發(fā)應(yīng)用系統(tǒng)常用的功能。作為一個小型的輕量級應(yīng)用服務(wù)器,Tomcat在中小型系統(tǒng)和并發(fā)訪問用戶不是很多的場合下被普遍使用,成為目前比較流行的Web 應(yīng)用服務(wù)器。

            而JBoss Web采用業(yè)界最優(yōu)的開源Java Web引擎, 將Java社區(qū)中下載量最大,用戶數(shù)最多,標(biāo)準(zhǔn)支持最完備的Tomcat內(nèi)核作為其Servlet容器引擎,并加以審核和調(diào)優(yōu)。單純的Tomcat性能有限,在很多地方表現(xiàn)有欠缺,如活動連接支持、靜態(tài)內(nèi)容、大文件和HTTPS等。除了性能問題,Tomcat的另一大缺點是它是一個受限的集成平臺,僅能運(yùn)行Java應(yīng)用程序。企業(yè)在使用時Tomcat,往往還需同時部署Apache Web Server以與之整合。此配置較為繁瑣,且不能保證性能的優(yōu)越性。

            JBoss在Tomcat的基礎(chǔ)上,對其進(jìn)行本地化,將Tomcat 以內(nèi)嵌的方式集成到 JBoss 中。JBoss Web通過使用APR和Tomcat本地技術(shù)的混合模型來解決Tomcat的諸多不足。混合技術(shù)模型從最新的操作系統(tǒng)技術(shù)里提供了最好的線程和事件處理。結(jié)果,JBoss Web達(dá)到了可擴(kuò)展性,性能參數(shù)匹配甚至超越了本地Apache HTTP服務(wù)器或者IIS。譬如JBoss Web能夠提供數(shù)據(jù)庫連接池服務(wù),不僅支持 JSP 等 Java 技術(shù),同時還支持其他 Web 技術(shù)的集成,譬如 PHP、.NET 兩大陣營。

            標(biāo)準(zhǔn)化是減小技術(shù)依賴風(fēng)險,保護(hù)投資最好的方式。JBoss Web率先支持全系列JEE Web標(biāo)準(zhǔn),從根本上保證了應(yīng)用“一次開發(fā),到處運(yùn)行”的特點,使應(yīng)用成品能方便地在JBoss Web和其他Java Web服務(wù)器之間輕易遷移。

            集多功能于一身,性能卓越

            作為Web 應(yīng)用服務(wù)器中的明星產(chǎn)品,JBoss Web服務(wù)器集多種功能于一身。其關(guān)鍵功能包括:完全支持Java EE、高度的擴(kuò)展性、快速的靜態(tài)內(nèi)容處理、群集、OpenSSL、URL重寫和綜合性。

            JBoss Web服務(wù)器具有原生特性和強(qiáng)大的可擴(kuò)展性,可支持多種并非基于Java的服務(wù)器內(nèi)容處理技術(shù),可同時運(yùn)行JSP, Servlet, Microsoft .NET , PHP 及 CGI,為其提供一個單一的、高性能的企業(yè)級部署平臺。

            與Tomcat 相比,JBoss Web在靜態(tài)資源訪問方面性能優(yōu)越。JBoss Web支持兩種組件模式——純Java和Native I/O。在Native組件的支持下,動態(tài)運(yùn)行不會受到任何影響,而靜態(tài)資源的訪問利用了操作系統(tǒng)本身提供的0拷貝傳送,CPU消耗降低,響應(yīng)時間縮短,吞吐率大大提高,混合的連接模式支持最大達(dá)到10000個并發(fā)客戶端的同時訪問,與Apache Web服務(wù)器相當(dāng)。部署于高性能的操作系統(tǒng),可利用JBoss Web對純Java和Native I/O兩種模式的支持,使得應(yīng)用在開發(fā)時可隨時跨平臺敏捷遷移,而部署于高性能的操作系統(tǒng)相關(guān)的Native環(huán)境。由于JBoss Web較好地解決了靜態(tài)資源的訪問性能問題,可在解決方案中把它直接作為強(qiáng)大的LVS的分發(fā)對象,和RHEL負(fù)載均衡系統(tǒng)結(jié)合,形成理論上無限線性擴(kuò)展的負(fù)載均衡場景。

            OpenSSL是業(yè)界最為快速和安全的開源傳輸組件,可借助操作系統(tǒng)和硬件的特性實現(xiàn)高效的安全承載。JBoss Web集成了OpenSSL,可提供高效的安全傳輸服務(wù),使得安全機(jī)制更上臺階。研究表明, JBoss Web中的SSL性能比單純的Tomcat快四倍。

            URL重寫功能可縮短URL,隱藏實際路徑提高安全性,易于用戶記憶和鍵入,及被搜索引擎收錄。Tomcat 不具備URL重寫功能,JBoss Web則可提供一個靈活的URL rewriting操作引擎,支持無限個規(guī)則數(shù)和規(guī)則條件。URL可被重寫以支持遺留的URL錯誤處理,或應(yīng)對服務(wù)器不時產(chǎn)生的其他問題。

            JBoss Web既可單獨運(yùn)行,也可無縫嵌入JBoss應(yīng)用服務(wù)器,成為JBoss中間件平臺的一部分。不僅后臺服務(wù)調(diào)用的性能將得以提升,也可利用以下JBoss平臺的特性提升Web應(yīng)用功能:

            基于JGroups的多種集群方案的支持

            基于Arjuna技術(shù)的JTA和JTS的事務(wù)處理支持

            優(yōu)化的線程池和連接池的支持

            基于JMX 控制臺的基本管理支持和JBoss On的高級管理維護(hù)支持

            基于JBoss AOP技術(shù)的面向方面架構(gòu)的支持

            Hibernate服務(wù)組件的支持

            專業(yè)團(tuán)隊支持

            業(yè)界大多數(shù)開源產(chǎn)品在技術(shù)方面富于創(chuàng)新性,但在可持續(xù)性,產(chǎn)品生命周期規(guī)劃,以及質(zhì)量保證方面缺乏有效保障,為軟件集成商和最終用戶所詬病。紅帽所力行的“專業(yè)化開源技術(shù)”則完美解決了這一問題。

            來自開源社區(qū)的JBoss Web,在紅帽專業(yè)化開源的錘煉下,在性能、擴(kuò)展性、穩(wěn)定性、安全性等方面,已成為一個達(dá)到企業(yè)級,甚至電信級標(biāo)準(zhǔn)的優(yōu)秀產(chǎn)品。紅帽不僅有專職的技術(shù)團(tuán)隊投入JBoss Web的開發(fā),而且具備專門的QA團(tuán)隊為產(chǎn)品作質(zhì)量保證。完善的集成測試和兼容性測試保證了JBoss Web自身的穩(wěn)定性,并保證了它的后向兼容和其他JBoss產(chǎn)品協(xié)作良好的互操作性。

            在服務(wù)體系保障方面,JBoss 開拓了以產(chǎn)品專家提供的專家級支持服務(wù)作為開源軟件強(qiáng)大后盾的軟件生態(tài)模式。公司以及龐大的 JBoss 授權(quán)服務(wù)合作伙伴網(wǎng)絡(luò)可為包括JBoss Web在內(nèi)的整個JEMS 產(chǎn)品套件提供全面的支持服務(wù)。與Tomcat相比,JBoss Web 可提供遷移服務(wù)與現(xiàn)場專家服務(wù),在遷移服務(wù)方面,專家指導(dǎo)應(yīng)用可從Tomcat向JBoss Web遷移,省時省力。獨特的服務(wù)訂閱模式,全力保障軟件生命周期,讓企業(yè)高枕無憂。

          posted @ 2009-12-05 17:46 睫晉姬 閱讀(307) | 評論 (0)編輯 收藏

          僅列出標(biāo)題  下一頁
          主站蜘蛛池模板: 邵武市| 崇阳县| 隆子县| 临湘市| 永德县| 锡林郭勒盟| 威宁| 海阳市| 卢龙县| 岫岩| 梨树县| 柳林县| 如东县| 徐闻县| 许昌市| 乐山市| 伊金霍洛旗| 吐鲁番市| 疏附县| 定安县| 德保县| 茶陵县| 吉安市| 迁西县| 永吉县| 航空| 澜沧| 宁德市| 边坝县| 西安市| 东海县| 洞口县| 施秉县| 宁明县| 永宁县| 通辽市| 肇州县| 无锡市| 横峰县| 鄂州市| 桓台县|