乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      JDK1.5新特性——java.util.concurrent 線程池(1)

       goldbomb 2008-01-13

      JDK5中的一個亮點就是將Doug Lea并發(fā)庫引入到Java標(biāo)準庫中。Doug Lea確實是一個牛人,能教書,能出書,能編碼,不過這在國外還是比較普遍的,而國內(nèi)的教授們就相差太遠了。

      一般的服務(wù)器都需要線程池,比如Web、FTP等服務(wù)器,不過它們一般都自己實現(xiàn)了線程池,比如以前介紹過的Tomcat、Resin和Jetty等,現(xiàn)在有了JDK5,我們就沒有必要重復(fù)造車輪了,直接使用就可以,何況使用也很方便,性能也非常高。

      package concurrent;
      import java.util.concurrent.ExecutorService;
      import java.util.concurrent.Executors;
      public class TestThreadPool {
        public static void main(String args[]) throws InterruptedException {
          // only two threads
          ExecutorService exec = Executors.newFixedThreadPool(2);
          for(int index = 0; index < 100; index++) {
            Runnable run = new Runnable() {
              public void run() {
                long time = (long) (Math.random() 1000);
                System.out.println("Sleeping " + time + "ms");
                  try {
                    Thread.sleep(time);
                  catch (InterruptedException e) {
                  }
              }
            };
            exec.execute(run);
          }
          // must shutdown
          exec.shutdown();
        }
      }

      上面是一個簡單的例子,使用了2個大小的線程池來處理100個線程。但有一個問題:在for循環(huán)的過程中,會等待線程池有空閑的線程,所以主線程會阻塞的。為了解決這個問題,一般啟動一個線程來做for循環(huán),就是為了避免由于線程池滿了造成主線程阻塞。不過在這里我沒有這樣處理。[重要修正:經(jīng)過測試,即使線程池大小小于實際線程數(shù)大小,線程池也不會阻塞的,這與Tomcat的線程池不同,它將Runnable實例放到一個“無限”的BlockingQueue中,所以就不用一個線程啟動for循環(huán),Doug Lea果然厲害]

      另外它使用了Executors的靜態(tài)函數(shù)生成一個固定的線程池,顧名思義,線程池的線程是不會釋放的,即使它是Idle。這就會產(chǎn)生性能問題,比如如果線程池的大小為200,當(dāng)全部使用完畢后,所有的線程會繼續(xù)留在池中,相應(yīng)的內(nèi)存和線程切換(while(true)+sleep循環(huán))都會增加。如果要避免這個問題,就必須直接使用ThreadPoolExecutor()來構(gòu)造??梢韵馮omcat的線程池一樣設(shè)置“最大線程數(shù)”、“最小線程數(shù)”和“空閑線程keepAlive的時間”。通過這些可以基本上替換Tomcat的線程池實現(xiàn)方案。

      需要注意的是線程池必須使用shutdown來顯式關(guān)閉,否則主線程就無法退出。shutdown也不會阻塞主線程。

       

      多長時間運行的應(yīng)用有時候需要定時運行任務(wù)完成一些諸如統(tǒng)計、優(yōu)化等工作,比如在電信行業(yè)中處理用戶話單時,需要每隔1分鐘處理話單;網(wǎng)站每天凌晨統(tǒng)計用戶訪問量、用戶數(shù);大型超時凌晨3點統(tǒng)計當(dāng)天銷售額、以及最熱賣的商品;每周日進行數(shù)據(jù)庫備份;公司每個月的10號計算工資并進行轉(zhuǎn)帳等,這些都是定時任務(wù)。通過 java的并發(fā)庫concurrent可以輕松的完成這些任務(wù),而且非常的簡單。

      package concurrent;
      import static java.util.concurrent.TimeUnit.SECONDS;
      import java.util.Date;
      import java.util.concurrent.Executors;
      import java.util.concurrent.ScheduledExecutorService;
      import java.util.concurrent.ScheduledFuture;
      public class TestScheduledThread {
        public static void main(String[] args) {
          final ScheduledExecutorService scheduler = Executors
              .newScheduledThreadPool(2);
          final Runnable beeper = new Runnable() {
            int count = 0;
            public void run() {
              System.out.println(new Date() " beep " (++count));
            }
          };
          // 1秒鐘后運行,并每隔2秒運行一次
          final ScheduledFuture<?> beeperHandle = scheduler.scheduleAtFixedRate(
              beeper, 12, SECONDS);
          // 2秒鐘后運行,并每次在上次任務(wù)運行完后等待5秒后重新運行
          final ScheduledFuture<?> beeperHandle2 = scheduler
              .scheduleWithFixedDelay(beeper, 25, SECONDS);
          // 30秒后結(jié)束關(guān)閉任務(wù),并且關(guān)閉Scheduler
          scheduler.schedule(new Runnable() {
            public void run() {
              beeperHandle.cancel(true);
              beeperHandle2.cancel(true);
              scheduler.shutdown();
            }
          }30, SECONDS);
        }
      }

      為了退出進程,上面的代碼中加入了關(guān)閉Scheduler的操作。而對于24小時運行的應(yīng)用而言,是沒有必要關(guān)閉Scheduler的。

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多