經驗不在于年限,在于積累---專注互聯網軟件開發

          把工作當事業做,把項目當作品做!

            BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
            55 Posts :: 0 Stories :: 66 Comments :: 0 Trackbacks
          (友情提示:本博文章歡迎轉載,但請注明出處:陳新漢,http://www.aygfsteel.com/hankchen
          一、并發集合類的選擇

              同步的集合類HashtableVector,以及同步的包裝器類Collections.synchronizedMapCollections.synchronizedList,為MapList提供了基本的有條件的線程安全的實現。然而,某些因素使得它們并不適用于具有高度并發性的應用程序中――它們的集合范圍的單鎖特性對于可伸縮性來說是一個障礙,而且,很多時候還必須在一段較長的時間內鎖定一個集合,以防止出現ConcurrentModificationExceptions異常。

          ConcurrentHashMapCopyOnWriteArrayList實現提供了更高的并發性,同時還保住了線程安全性,只不過在對其調用者的承諾上打了點折扣。ConcurrentHashMapCopyOnWriteArrayList并不是在您使用HashMapArrayList的任何地方都一定有用,但是它們是設計用來優化某些特定的公用解決方案的。許多并發應用程序將從對它們的使用中獲得好處。

          總結:在多線程并發情況下,為了避免ConcurrentModificationExceptions異常,建議使用ConcurrentHashMapCopyOnWriteArrayList

          還有下面的幾個可以考慮:ConcurrentLinkedQueue、CopyOnWriteArraySet、LinkedBlockingQueue、ArrayBlockingQueue
           

          二、高效的乘除運算

          服務器計算時,對于乘除運算,采用下面的方式:

          A*2=a<<1

          A/2=a>>1

          這樣可以提高運算效率。

           

          三、原子自增器

          多線程環境下, AtomicInteger 可用在應用程序中(如以原子方式增加的計數器),并且不能用于替換Integer。但是,此類確實擴展了 Number,允許那些處理基于數字類的工具和實用工具進行統一訪問。

          例如:

              private AtomicInteger bomdIdCreator = new AtomicInteger(); //自增序列號

              /**

               *得到新的炸彈ID,保持自增

               *@return

               */

              public int getNewBombID(){

                   return bomdIdCreator.addAndGet(1);

          }

          四、多線程鎖機制實現

          多線程環境下,為了避免資源競爭,引入了鎖機制。一般實現鎖機制有下面幾種方法:

          1. 同步方法、同步塊:synchronized

          2. 監視器方法:(waitnotifynotifyAll

          3. ReentrantLock 

          注意:ReentrantLock是一個可重入的互斥鎖
          Lock,它具有與使用 synchronized 方法和語句所訪問的隱式監視器鎖相同的一些基本行為和語義,但功能更強大。

          例如:建議總是立即實踐,使用 lock 塊來調用 try,在之前/之后的構造中,最典型的代碼如下:

           class X {

             private final ReentrantLock lock = new ReentrantLock();

             // ...

             public void m() {

               lock.lock(); // block until condition holds

               try {

                 // ... method body

               } finally {

                 lock.unlock()

               }

             }

           }

           

          五、線程池的實現方式

          Doug Lea 編寫了一個優秀的并發實用程序開放源碼庫 util.concurrent,它包括互斥、信號量、諸如在并發訪問下執行得很好的隊列和散列表之類集合類以及幾個工作隊列實現。該包中的 ThreadPoolExecutor類是一種有效的、廣泛使用的以工作隊列為基礎的線程池的正確實現。您無須嘗試編寫您自己的線程池,這樣做容易出錯,相反您可以考慮使用 util.concurrent中的一些實用程序。

          線程池可以解決兩個不同問題:由于減少了每個任務調用的開銷,它們通常可以在執行大量異步任務時提供增強的性能,并且還可以提供綁定和管理資源(包括執行集合任務時使用的線程)的方法。

          強烈建議程序員使用較為方便的Executors工廠方法Executors.newCachedThreadPool()(無界線程池,可以進行自動線程回收)、Executors.newFixedThreadPool(int)(固定大小線程池)和Executors.newSingleThreadExecutor()(單個后臺線程),它們均為大多數使用場景預定義了設置。

          例如:

          public class ThreadPoolExecutorTest {

              final static ExecutorService threadPool=Executors.newCachedThreadPool(); //簡單線程池實現

              /**

               * @param args

               */

              public static void main(String[] args) {

                 for(int i=0;i<10;i++){

                     threadPool.execute(new Runnable(){

                        public void run() {

                            System.out.println("aaa"+this.getClass().getName());

                            //do other things

                        }

                     });

                 }

              }

          }

           

          六、實現定時任務的幾種方式比較

          1. 使用原始的Timer

          2.  ScheduledThreadPoolExecutor JDK 1.5新增)

          3.  Quatz開源項目

          Java 5.0開始,java.util.concurrent包中增加了一個ScheduledThreadPoolExecutor類,用來實現定時任務和線程池的管理,比起Timer簡陋的實現是要強大得多。利用ScheduledThreadPoolExecutorscheduleAtFixedRate()scheduleWithFixedDelay()兩個方法就可以實現任務調度的基本功能,從前用Timer實現的功能應該要遷移到scheduleWithFixedDelay()上了。

          注意:ScheduledThreadPoolExecutor是實現ScheduledExecutorService接口的具體類。

          1)public static final ScheduledExecutorService scheduledExecutor = Executors.newScheduledThreadPool(2);
          2)public static final ScheduledThreadPoolExecutor scheduledExecutor=new ScheduledThreadPoolExecutor(2);
          這兩種方式是一樣的,都是得到一個可調度的線程池。

           

          ScheduledThreadPoolExecutorTimer的區別:

          1.      Timer的主要方法有:

          // 安排在指定的時間執行

          void schedule(TimerTask task, Date time)

          // 安排在指定的時間開始以重復的延時執行

          void schedule(TimerTask task, Date firstTime, long period)

          // 安排在指定的延遲后執行

          void schedule(TimerTask task, long delay)

          // 安排在指定的延遲后開始以重復的延時執行

          void schedule(TimerTask task, long delay, long period)

          // 安排在指定的時間開始以重復的速率執行

          void scheduleAtFixedRate(TimerTask task, Date firstTime, long period)

          // 安排在指定的延遲后開始以重復的速率執行

          void scheduleAtFixedRate(TimerTask task, long delay, long period)

           

          注:重復的延時重復的速率的區別在于,前者是在前一個任務的執行結束后間隔period時間再開始下一次執行;而scheduleAtFixedRate則是會盡量按照任務的初始時間來按照間隔period時間執行。如果一次任務執行由于某些原因被延遲了,用schedule()調度的后續任務同樣也會被延遲,而用scheduleAtFixedRate()則會快速的開始兩次或者多次執行,是后續任務的執行時間能夠趕上來。

           

          2.      ScheduledThreadPoolExecutor的主要方法:

          // 在指定的延遲后執行

          <V>ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit)

          // 在指定的延遲后執行

          ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit)

          // 在指定的延遲后以固定速率執行(類似Timer.scheduleAtFixedRate())

          ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)

          // 在指定的延遲后以固定間隔執行(類似Timer.schedule())

          ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit)

           

          比較:

          1Timer對調度的支持是基于絕對時間的,因此任務對系統時間的改變是敏感的;而ScheduledThreadPoolExecutor支持相對時間。

          2Timer使用單線程方式來執行所有的TimerTask,如果某個TimerTask很耗時則會影響到其他TimerTask的執行;而ScheduledThreadPoolExecutor則可以構造一個固定大小的線程池來執行任務。

          3Timer不會捕獲由TimerTask拋出的未檢查異常,故當有異常拋出時,Timer會終止,導致未執行完的TimerTask不再執行,新的TimerTask也不能被調度;ScheduledThreadPoolExecutor對這個問題進行了妥善的處理,不會影響其他任務的執行。

          結論:Timer有這么多的缺點,如果是使用JDK1.5以上的話,應該沒什么理由要使用Timer來進行調度。
          (友情提示:本博文章歡迎轉載,但請注明出處:陳新漢,http://www.aygfsteel.com/hankchen

          posted on 2009-12-30 16:54 hankchen 閱讀(2717) 評論(1)  編輯  收藏 所屬分類: 學習心得

          Feedback

          # re: Java 5.0 高性能程序開發總結(不斷補充) 2010-01-05 11:31 x3
          一:
          ConcurrentHashMap和CopyOnWriteArrayList
          是否可以完全替代Collections.synchronizedMap和Collections.synchronizedList ?
          二:感覺差不了多少,還降低了代碼可讀性,除非你們公司都是做C的  回復  更多評論
            

          主站蜘蛛池模板: 城固县| 辉南县| 怀化市| 湖南省| 定襄县| 大连市| 高州市| 克东县| 荥阳市| 济南市| 邳州市| 黄大仙区| 彭州市| 旬邑县| 铜鼓县| 铁岭市| 中方县| 阳原县| 本溪| 从化市| 尼玛县| 桦南县| 百色市| 曲水县| 东宁县| 武冈市| 镇宁| 建阳市| 莒南县| 江口县| 怀集县| 丽江市| 甘泉县| 桃园县| 武山县| 宜兰县| 潮安县| 宁津县| 克山县| 囊谦县| 桐梓县|