失敗者,每每是熱度只有五分鐘的人;成功者,每每是堅持最後五分鐘的人。
你好,我是夢陽辰,期待與你相遇!java
10年前單核CPU電腦,假的多線程,像馬戲團小丑玩多個球,CPU須要來回切換。如今是多核電腦,多個線程各自跑在獨立的CPU上,不用切換效率高。api
線程池的優點:
線程池作的工做只要是控制運行的線程數量,處理過程當中將任務放入隊列,而後在線程建立後啓動這些任務,若是線程數量超過了最大數量,超出數量的線程排隊等候,等其餘線程執行完畢,再從隊列中取出任務來執行。數組
它的主要特色爲:線程複用;控制最大併發數;管理線程。多線程
第一:下降資源消耗。經過重複利用已建立的線程下降線程建立和銷燬形成的銷耗。併發
第二:提升響應速度。當任務到達時,任務能夠不須要等待線程建立就能當即執行。框架
第三:提升線程的可管理性。線程是稀缺資源,若是無限制的建立,不只會銷耗系統資源,還會下降系統的穩定性,使用線程池能夠進行統一的分配,調優和監控。dom
java.util.concurrent Interface Executor
子接口:異步
java.util.concurrent Interface ExecutorService
Executors是一個輔助工具類。ide
Executors.newFixedThreadPool(int)執行長期任務性能好,建立一個線程池,—池 有N個固定的線程,有固定線程數的線程
package Part5;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class ThreadPoolDemo1 { public static void main(String[] args) { ExecutorService threadPool = Executors.newFixedThreadPool(5);//一個池5個受理線程,相似於一個銀行有五個受理窗口 try{ //模擬20個顧客辦理業務 for(int i = 1;i<=20;i++){ threadPool.execute(()->{ System.out.println(Thread.currentThread().getName()+"\t 在辦理業務!"); }); } }catch (Exception e){ e.printStackTrace(); }finally { threadPool.shutdown(); } }}
2.Executors.newSingleThreadExecutor()一個任務一個任務的執行,一池一線程 3.Executors.newCachedThreadPool()執行不少短時間異步任務,線程池根據須要建立新線程, 但在先前構建的線程可用時將重用它們。可擴容,遇強則強
package Part5;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.TimeUnit;public class ThreadPoolDemo1 { public static void main(String[] args) { //ExecutorService threadPool = Executors.newFixedThreadPool(5);//一個池5個受理線程,相似於一個銀行有五個受理窗口 //ExecutorService threadPool = Executors.newSingleThreadExecutor();//一個池1個受理線程,相似於一個銀行有1個受理窗口 ExecutorService threadPool = Executors.newCachedThreadPool();//一個池N個受理線程,相似於一個銀行有N個受理窗口 try{ //模擬20個顧客辦理業務 for(int i = 1;i<=20;i++){ threadPool.execute(()->{ System.out.println(Thread.currentThread().getName()+"\t 在辦理業務!"); }); } }catch (Exception e){ e.printStackTrace(); }finally { threadPool.shutdown(); } }}
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) { if (corePoolSize < 0 || maximumPoolSize <= 0 || maximumPoolSize < corePoolSize || keepAliveTime < 0) throw new IllegalArgumentException(); if (workQueue == null || threadFactory == null || handler == null) throw new NullPointerException(); this.acc = System.getSecurityManager() == null ? null : AccessController.getContext(); this.corePoolSize = corePoolSize; this.maximumPoolSize = maximumPoolSize; this.workQueue = workQueue; this.keepAliveTime = unit.toNanos(keepAliveTime); this.threadFactory = threadFactory; this.handler = handler; }
一、在建立了線程池後,開始等待請求。函數
二、當調用execute()方法添加一個請求任務時,線程池會作出以下判斷:
2.1若是正在運行的線程數量小於corePoolSize,那麼立刻建立線程運行這個任務;2.2若是正在運行的線程數量大於或等於corePoolSize,那麼將這個任務放入隊列;
2.3若是這個時候隊列滿了且正在運行的線程數量還小於maximumPoolSize,那麼仍是要建立非核心線程立2.4若是隊列滿了且正在運行的線程數量大於或等於maximumPoolSize,那麼線程池會啓動飽和拒絕策略來
三、當一個線程完成任務時,它會從隊列中取下一個任務來執行。
四、當一個線程無事可作超過必定的時間(keepAliveTime)時,線程會判斷:
若是當前運行的線程數大於corePoolSize,那麼這個線程就被停掉。
因此線程池的全部任務完成後,它最終會收縮到corePoolSize的大小。
強制線程池不容許使用Executors 去建立,而是經過ThreadPoolExecutor的方式這樣的處理方式讓寫的同窗更加明確線程池的運行規則,規避資源耗盡的風險。
說明: Executors返回的線程池對象的弊端以下:
FixedThreadPool和 singleThreadPool:
容許的請求隊列長度爲Integer.MAx_VALUE,可能會堆積大量的請求,從而致使OOM
cachedThreadPool和 ScheduledThreadPool:
容許的建立線程數量爲Integer.NAX_VALUE,可能會建立大量的線程,從而致使OOM。
等待隊列已經排滿了,再也塞不下新任務了同時,
線程池中的max線程也達到頁,沒法繼續爲新任務服務。
這個是時候咱們就須要拒絕策略機制合理的處理這個問題。
流(Stream)究竟是什麼呢?
是數據渠道,r用於操做數據源(集合、數組等)所生成的元素序列。
「集合講的是數據,流講的是計算!」
Stream本身不會存儲元素,Stream不會改變源對象。
相反他們會返回一個持有結果的新Stream。
Stream操做是延遲執行的。
這意味着他們會等到須要結果的時候才執行。
建立一個Stream: 一個數據源(數組、集合)
中間操做:一箇中間操做,處理數據源數據
終止操做:一個終止操做,執行中間操做鏈,產生結果
源頭=>中間流水線=>結果
package Part5;import com.sun.xml.internal.ws.api.model.wsdl.WSDLOutput;import org.w3c.dom.ls.LSOutput;import java.util.Arrays;import java.util.List;public class StreamDemo1 { public static void main(String[] args) { User u1 = new User(11,"a",23); User u2 = new User(12,"b",24); User u3 = new User(13,"c",22); User u4 = new User(14,"d",28); User u5 = new User(16,"e",26); List<User> list = Arrays.asList(u1,u2,u3,u4,u5); list.stream().filter(t->{return t.getId()%2 == 0;}) .filter(t->{return t.getAge()>24;}) .map(m->{return m.getName().toUpperCase();}) .sorted((o1,o2)->{return o2.compareTo(o1);}).limit(1) .forEach(System.out::println); }}
java.lang.Object java.util.concurrent.AbstractExecutorService java.util.concurrent.ForkJoinPool
java.util.concurrent.ForkJoinTask<V> java.util.concurrent.RecursiveTask<V> //遞歸抽象類
package Part5;import java.util.concurrent.ExecutionException;import java.util.concurrent.ForkJoinPool;import java.util.concurrent.ForkJoinTask;import java.util.concurrent.RecursiveTask;class MyTask extends RecursiveTask<Integer>{//資源類,RecursiveTask抽象類爲遞歸 private static final Integer ADD_VALUE = 10; private int begin; private int end; private int result; public MyTask(int begin, int end) { this.begin = begin; this.end = end; } @Override protected Integer compute() { if((end-begin)<=ADD_VALUE){ for(int i=begin;i<=end;i++){ result = result + i; } }else{ int middle = (end+begin)/2; MyTask task1 = new MyTask(begin,middle); MyTask task2 = new MyTask(middle+1,end); task1.fork();//分 task2.fork();//分支 result = task1.join()+task2.join();//合併結果 } return result; }}public class ForkJoinDemo { public static void main(String[] args) throws ExecutionException, InterruptedException { MyTask myTask = new MyTask(0,100); ForkJoinPool threadPool = new ForkJoinPool(); ForkJoinTask<Integer> forkJoinTask = threadPool.submit(myTask);//提交任務 System.out.println(forkJoinTask.get());//獲取結果 threadPool.shutdown() ; }}
java.lang.Object java.util.concurrent.CompletableFuture<T>
測試:
package Part5;import java.util.concurrent.CompletableFuture;import java.util.concurrent.ExecutionException;public class CompletableFutrueDemo { public static void main(String[] args) throws ExecutionException, InterruptedException { CompletableFuture<Void> completableFuture = CompletableFuture.runAsync(()->{ System.out.println(Thread.currentThread().getName()+"沒有返回值!"); }); completableFuture.get(); //異步回調 CompletableFuture<Integer> completableFuture2 = CompletableFuture.supplyAsync(()->{ System.out.println(Thread.currentThread().getName()+"有返回值!"); int f = 5/0; return 1; }); completableFuture2.whenComplete((t,u)->{//正常時的狀況 System.out.println("***:"+t); }).exceptionally(f->{//異常時狀況 System.out.println("***excption:"+f.getMessage()); return 444; }); }}
Don’t look forward to tomorrow, don’t miss yesterday, to grasp today.