天天看點

Java多線程應用(1)

目标:掌握多線程的使用及應用場景
  • 怎麼使用多線程
    // 盡量不要如此使用
    new Thread(new Runnable() {
           @Override
           public void run() {
    
           }
    }).start();
    // 通過線程池友善管理
    Executor executor = Executors.newCachedThreadPool();
    executor.execute(runnable);
               
  • 程序和線程的差別

    其實沒有可比性,之是以大家喜歡用來比較是因為他們都可以并行,兩個程序可以并行,兩個線程也可以并行,是以大家喜歡用來對比。

    但其實差别還是比較大的,程序在作業系統中是擁有獨立空間的,并且程序間是不共享的,而一個程序中可能會包含很多個線程,而線程間是可以共享資源。

  • CPU線程與作業系統的線程怎麼了解

    CPU線程就是我們平時聽到的幾核CPU的概念,比如6核的CPU,它的CPU線程就是6,它表示CPU同時隻能幹六件事,而我們代碼中所開的線程其實是作業系統的線程,作業系統通過時間分片可以将線程開的很多很多。

  • ThreadPoolExecutor

    以ThreadPoolExecutor為例,他的構造函數裡面會有幾個重要的參數:

    Java多線程應用(1)
  • 第一個參數corePoolSize表示該線程池需要保留的線程數量,即使在空閑的時候。

    maximumPoolSize表示目前線程池最大可以擁有多少個線程,當線程池中開到最大,并且所有線程都在執行任務,此時如果有任務來了,就需要等待線程池中有空閑的線程釋放出來。

    keepAliveTime表示當線程池中超過corePoolSize的部分,在空閑狀态時可以繼續保留的時間,一旦超過這個時間就會銷毀。

    timeUnit表示上面參數的時間機關

    workQueue顯然就是線程池正在滿池運作,新的待執行任務需要放在這個隊列裡等待空閑線程的到來。

  • newFixedThreadPool(int nThreads)

    這個方法是用來創在保持特定數量的線程池,因為這個數量是既是線程池的最大線程數,也是線程池需要保留的線程數,是以,線程也不好增加,在空閑狀态時也不能回收多餘的。

    是以它的應用場景也是比較少的,一般是用來集中處理一些爆發性的事物後立即釋放,比如突然來了20張圖檔要處理,這個時候肯定不能一張一張的處理,可以開多線程并行處理,如下所示:

    List<Bitmap> imgs = somewhereGetImgs(20);
    ExecutorService executor = Executors.newFixedThreadPool(20);
    for(Bitmap bitmap: imgs) {
    	// 向線程池中扔了20個任務同時執行
    	executor.execute(processImgRunnable);
    }
    // 執行完就快速的回收
    executor.shutdown();
               
  • Callable

    有傳回值的Runnable。

    舉個例子:

  • Java多線程應用(1)

    既然要放到異步線程裡去執行,那傳回結果又有什麼意義呢,難道要阻塞主線程一直等任務線程執行完?

    上面的例子就說明了部分使用場景,我們可以先拿到一個future的執行個體來在後面進行判斷是否任務執行完了(當然,不一定是上面死循環的方式),實際可以根據具體業務來做。

繼續閱讀