一、ThreadPoolExecutor 簡要實例
獲取子線程執行結果后再執行主線程 ,這樣可將復雜耗時業務拆分執行返回結果,將結果匯總整理。
多個線程時可以 利用Future阻塞,當其它線程執行完畢獲得結果,再執行主線程
/** * ThreadPoolExecutor 線程池使用 * 1、多個線程時可以 利用Future阻塞,當其它線程執行完畢獲得結果,再執行主線程 */ @Test public void simpleMethod() { ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(9, 100, 100, TimeUnit.SECONDS, new SynchronousQueue<>()); try { List<String> list1 = new ArrayList<String>(); Callable<Integer> call1 = new Callable<Integer>() { @Override public Integer call() throws Exception { for (int j = 0; j < 10; j++) { list1.add("i:" + j); } return 10; } }; Callable<Integer> call2 = new Callable<Integer>() { @Override public Integer call() throws Exception { for (int j = 0; j < 10; j++) { list1.add("i:" + j); } return 10; } }; Callable<Integer> call3 = new Callable<Integer>() { @Override public Integer call() throws Exception { for (int j = 0; j < 10; j++) { list1.add("i:" + j); } return 10; } }; Callable<Integer> call4 = new Callable<Integer>() { @Override public Integer call() throws Exception { for (int j = 0; j < 10; j++) { list1.add("i:" + j); } return 10; } }; Future<Integer> f1 = poolExecutor.submit(call1); Future<Integer> f2 = poolExecutor.submit(call2); Future<Integer> f3 = poolExecutor.submit(call3); Future<Integer> f4 = poolExecutor.submit(call3); ArrayList<String> ss = new ArrayList<>(); f1.get(); f2.get(); f3.get(); f4.get(); // Thread.sleep(1000); System.out.println("list1.size() = " + list1.size()); } catch (Exception e) { e.printStackTrace(); } }
二、CountDownLanch 簡要實例
場景:當指定幾個線程執行完后再執行 主線程,或使用2個CountDownLanch 對象進行多組子線程控制
/** * CountDownLatch 阻塞執行完預其的線程才會執行,后續方法業務處理 */ @Test public void lanchTest() { try { ThreadPoolExecutor thredPool = new ThreadPoolExecutor(20, 100, 1000, TimeUnit.SECONDS, new ArrayBlockingQueue<>(10)); CountDownLatch cutdownLanch = new CountDownLatch(3); thredPool.execute(new Runnable() { @Override public void run() { System.out.println("我是子線程-id:" + Thread.currentThread().getName()); cutdownLanch.countDown(); } }); thredPool.execute(new Runnable() { @Override public void run() { System.out.println("我是子線程-id:" + Thread.currentThread().getName()); cutdownLanch.countDown(); } }); thredPool.execute(new Runnable() { @Override public void run() { System.out.println("我是子線程-id:" + Thread.currentThread().getName()); cutdownLanch.countDown(); } }); System.out.println("這是主線程在下一句阻塞,current-thread-id:" + Thread.currentThread().getName()); cutdownLanch.await(); System.out.println("子線程執行完畢"); } catch (InterruptedException e) { e.printStackTrace(); } }
ps: 線程池各參數 先估算,再加上壓力測試進行調整 。