Java線程池Executor使用

來源:互聯網
上載者:User

標籤:Java.並發編程

  • 引言
    合理利用線程池能夠帶來三個好處。第一:降低資源消耗。通過重複利用已建立的線程降低線程建立和銷毀造成的消耗。第二:減少系統對於,外部 服務的回應時間的等待。第三:提高線程的可管理性。線程是稀缺資源,如果無限制的建立,那麼系統記憶體就會消耗完,所以就用引用到線程池的概念。
    線程池主要就瞭解一個方法就可以了

    瞭解幾個參數
    corePoolSize(線程池的基本大小):當提交一個任務到線程池時,線程池會建立一個線程來執行任務,即使其他閒置基本線程能夠執行新任務也會建立線程,等到需要執行的任務數大於線程池基本大小時就不再建立。如果調用了線程池的prestartAllCoreThreads方法,線程池會提前建立並啟動所有基本線程。
    runnableTaskQueue(任務隊列):用於儲存等待執行的任務的阻塞隊列。可以選擇以下幾個阻塞隊列。
    ArrayBlockingQueue:是一個基於數組結構的有界阻塞隊列,此隊列按 FIFO(先進先出)原則對元素進行排序。
    LinkedBlockingQueue:一個基於鏈表結構的阻塞隊列,此隊列按FIFO (先進先出) 排序元素,輸送量通常要高於ArrayBlockingQueue。靜態Factory 方法Executors.newFixedThreadPool()使用了這個隊列。
    SynchronousQueue:一個不儲存元素的阻塞隊列。每個插入操作必須等到另一個線程調用移除操作,否則插入操作一直處於阻塞狀態,輸送量通常要高於LinkedBlockingQueue,靜態Factory 方法Executors.newCachedThreadPool使用了這個隊列。
    PriorityBlockingQueue:一個具有優先順序得無限阻塞隊列。
    maximumPoolSize(線程池最大大小):線程池允許建立的最大線程數。如果隊列滿了,並且已建立的線程數小於最大線程數,則線程池會再建立新的線程執行任務。值得注意的是如果使用了無界的任務隊列這個參數就沒什麼效果。
    ThreadFactory:用於設定建立線程的工廠,可以通過線程工廠給每個建立出來的線程設定更有意義的名字,Debug和定位問題時非常又協助。
    RejectedExecutionHandler(飽和策略):當隊列和線程池都滿了,說明線程池處於飽和狀態,那麼必須採取一種策略處理提交的新任務。這個策略預設情況下是AbortPolicy,表示無法處理新任務時拋出異常。以下是JDK1.5提供的四種策略。n AbortPolicy:直接拋出異常。
  • CallerRunsPolicy:只用調用者所線上程來運行任務。
    DiscardOldestPolicy:丟棄隊列裡最近的一個任務,並執行當前任務。
    DiscardPolicy:不處理,丟棄掉。
    當然也可以根據應用情境需要來實現RejectedExecutionHandler介面自訂策略。如記錄日誌或持久化不能處理的任務。
    keepAliveTime(線程活動保持時間):線程池的背景工作執行緒空閑後,保持存活的時間。所以如果任務很多,並且每個任務執行的時間比較短,可以調大這個時間,提高線程的利用率。
    TimeUnit(線程活動保持時間的單位):可選的單位有天(DAYS),小時(HOURS),分鐘(MINUTES),毫秒(MILLISECONDS),微秒(MICROSECONDS, 千分之一毫秒)和毫微秒(NANOSECONDS, 千分之一微秒)。

                 int righesSize=rights.size(); //擷取需要對資料連線的次數                    final CountDownLatch countDownLatch=new CountDownLatch(righesSize);  //並發工具用於堵塞等待線程執行完成                    ExecutorService executorService= Executors.newCachedThreadPool();//使用線程池                    int nThreads=Runtime.getRuntime().availableProcessors(); //擷取機器的cpu核心數                    final Semaphore semp = new Semaphore(nThreads); //限制線程數                    for( int i=0;i<righesSize;i++){                    final AppRights info=rights.get(i);                        Runnable run = new Runnable() { //開始實行線程啦                            @Override                            public void run() {                                try {                                    // 擷取線程池的許可(有空閑線程的時候)                                    semp.acquire();                                } catch (Exception e) {                                    e.printStackTrace();                                }                                    //商務邏輯處理                                    // for (AppRights info : rights) { //效率不高                                    MenuCountVo vo = new MenuCountVo();                                    vo.setMenuId(info.getMenuId());                                    int notReadCount = 0;                                    String menuCode = info.getMenuCode();                                try {                                    switch (menuCode) {                                        case "notice":                                            //調用天使                                            JSONObject json = new JSONObject();                                            json.put("userCode", userCode);                                            json.put("source", "sfa");                                            notReadCount = infomationService.getUnreadInform(json);                                            break;                                        case "sfa_store_patrol":                                            notReadCount = storePatrolService.getNotLeaveStoreNum(userCode);//統計門店巡檢未離店記錄                                            break;                                        case "sfa_store_order_mrg"://統計門店訂單的未讀數角標,add by Deco 20171012                                            notReadCount = storeOrderService.getCornerNum(userCode);                                            break;                                    }                                } catch (Exception e) {                                    notReadCount = 0;                                    e.printStackTrace();                                }                                vo.setNotReadCount(notReadCount);                                menuCountList.add(vo);                                // 商務邏輯處理完後,釋放線程及堵塞                                semp.release();                                countDownLatch.countDown();                            }                        };                        executorService.execute(run);                    }                    countDownLatch.await(); //全部執行完成之後就往下執行啦                    return new JsonResult(ApiCode.OK, Boolean.TRUE).data("menuCountList", menuCountList);                }            default :new JsonResult(ApiCode.EXCEPTION, Boolean.TRUE);        }        參考資料        Java並發編程實戰。        JDK1.8源碼。

    Java線程池Executor使用

    聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.