java8中forkjoin和optional框架使用
并行流與串行流
并行流就是把一個內(nèi)容分成多個數(shù)據(jù)塊,并用不同的線程分別處理每個數(shù)據(jù)塊的流。
java 8 中將并行進(jìn)行了優(yōu)化,我們可以很容易的對數(shù)據(jù)進(jìn)行并行操作。Stream API 可以聲明性地通過 parallel()與 sequential()在并行流與順序流之間進(jìn)行切換。
了解 Fork/Join 框架
Fork/Join 框架:就是在必要的情況下,將一個大任務(wù),進(jìn)形拆分(fork)成若干個小任務(wù)(拆到不可再拆時),再將一個個的小任務(wù)運行的結(jié)果進(jìn)行join匯總。
Fork/Join 框架與傳統(tǒng)線程池的區(qū)別:
采用“工作竊取”模式(work-stealing):
當(dāng)執(zhí)行新的任務(wù)時,它可以將其拆分成更小的任務(wù)執(zhí)行,并將小任務(wù)加到線程隊列中,然后再從一個隨機(jī)線程的隊列中偷一個并把它放在自己的隊列中。
相對于一般的線程池實現(xiàn),fork/join框架的優(yōu)勢體現(xiàn)在對其中包含的任務(wù)的處理方式上.在一般的線程池中,如果一個線程正在執(zhí)行的任務(wù)由于某些原因無法繼續(xù)運行,那么該線程會處于等待狀態(tài).而在fork/join框架實現(xiàn)中,如果某個子問題由于等待另外一個子問題的完成而無法繼續(xù)運行.那么處理該子問題的線程會主動尋找其他尚未運行的子問題來執(zhí)行.這種方式減少了線程的等待時間,提高了性能。
import java.time.Duration; import java.time.Instant; import java.util.concurrent.ForkJoinPool; import java.util.concurrent.ForkJoinTask; import java.util.concurrent.RecursiveTask; import java.util.stream.LongStream; public class TestForkJoin { public static void main(String[] xx){ } private static void test1(){ Instant start=Instant.now(); ForkJoinPool pool=new ForkJoinPool(); ForkJoinTask<Long> task = new ForkJoinCalculate(0L, 10000000000L); long sum = pool.invoke(task); System.out.println(sum); Instant end=Instant.now(); System.out.println("消耗時間"+Duration.between(start, end).toMillis()+"ms");//消耗時間3409ms } private static void test2(){ Instant start=Instant.now(); Long sum = LongStream.rangeClosed(0L, 10000L) .parallel() .reduce(0,Long::sum); System.out.println(sum); Instant end=Instant.now(); System.out.println("消耗時間" + Duration.between(start, end).toMillis()+"ms");//消耗時間2418ms } } class ForkJoinCalculate extends RecursiveTask<Long>{ private static final long serialVersionUID = 1234567890L;//序列號 private long start; private long end; private static final long THRESHOLD=2500000000L;//臨界值 public ForkJoinCalculate(long start,long end) { this.start=start; this.end=end; } @Override protected Long compute() { long length = end - start; if(length <= THRESHOLD){ long sum=0; for(long i = start; i <= end; i++){ sum += i; } return sum; }else{ long middle = (start+end)/2; ForkJoinCalculate left = new ForkJoinCalculate(start, middle); left.fork(); ForkJoinCalculate right=new ForkJoinCalculate(middle+1, end); right.fork(); return left.join() + right.join(); } } }
Optional類
Optional< T>類(java.util.Optional) 是一個容器類,代表一個值存在或不存在。
原來用null表示一個值不存在,現(xiàn)在 Optional可以更好的表達(dá)這個概念。并且可以避免空指針異常。
常用方法:
Optional.of(T t) : 創(chuàng)建一個 Optional 實例
Optional.empty() : 創(chuàng)建一個空的 Optional 實例
Optional.ofNullable(T t):若 t 不為 null,創(chuàng)建 Optional 實例,否則創(chuàng)建空實例
isPresent() : 判斷是否包含值
orElse(T t) : 如果調(diào)用對象包含值,返回該值,否則返回t
orElseGet(Supplier s) :如果調(diào)用對象包含值,返回該值,否則返回 s 獲取的值
map(Function f): 如果有值對其處理,并返回處理后的Optional,否則返回 Optional.empty()
flatMap(Function mapper):與 map 類似,要求返回值必須是Optional
public class OptionalTest1 { public static void main(String[] args){ String s = new String("Ha"); // Optional<String> op = Optional.of(null); // // String s1 = op.get(); // System.out.println(s1); // Optional<String> op1 = Optional.empty(); // String s1 = op1.get(); // System.out.println(s1); Optional<String> op1 = Optional.ofNullable(null); // System.out.println(op1.isPresent()); // System.out.println(op1.orElse(new String("Google"))); //System.out.println(op1.orElseGet(() -> new String("Ali"))); Optional<String> op2 = op1.map((x) -> x.toLowerCase()); String s2 = op2.get(); System.out.println(s2); } }
@Test public void test5(){ Man man=new Man(); String name=getGodnessName(man); System.out.println(name); } //需求:獲取一個男人心中女神的名字 public String getGodnessName(Man man){ if(man!=null){ Godness g=man.getGod(); if(g!=null){ return g.getName(); } } return "蒼老師"; } //運用Optional的實體類 @Test public void test6(){ Optional<Godness> godness=Optional.ofNullable(new Godness("林志玲")); Optional<NewMan> op=Optional.ofNullable(new NewMan(godness)); String name=getGodnessName2(op); System.out.println(name); } public String getGodnessName2(Optional<NewMan> man){ return man.orElse(new NewMan()) .getGodness() .orElse(new Godness("蒼老師")) .getName(); } //注意:Optional 不能被序列化 public class NewMan { private Optional<Godness> godness = Optional.empty(); private Godness god; public Optional<Godness> getGod(){ return Optional.of(god); } public NewMan() { } public NewMan(Optional<Godness> godness) { this.godness = godness; } public Optional<Godness> getGodness() { return godness; } public void setGodness(Optional<Godness> godness) { this.godness = godness; } @Override public String toString() { return "NewMan [godness=" + godness + "]"; } }
以上就是我們給大家整理的java8中forkjoin和optional框架使用心得的全部內(nèi)容,大家在學(xué)習(xí)的時候如果還有任何不明白的地方可以在下方的留言區(qū)討論。
相關(guān)文章
SpringBoot開發(fā)詳解之Controller接收參數(shù)及參數(shù)校驗
數(shù)據(jù)校驗是為了使系統(tǒng)更完整,數(shù)據(jù)更精確,同時也有利于維護(hù)數(shù)據(jù)的安全性,下面這篇文章主要給大家介紹了關(guān)于SpringBoot開發(fā)詳解之Controller接收參數(shù)及參數(shù)校驗的相關(guān)資料,需要的朋友可以參考下2022-03-03JDBC中PreparedStatement詳解以及應(yīng)用場景實例介紹
PreparedStatement對象代表的是一個預(yù)編譯的SQL語句,用它提供的setter方法可以傳入查詢的變量,這篇文章主要給大家介紹了關(guān)于JDBC中PreparedStatement詳解以及應(yīng)用場景實例介紹的相關(guān)資料,需要的朋友可以參考下2024-02-02Kotlin開發(fā)Android應(yīng)用實例詳解
這篇文章主要介紹了Kotlin開發(fā)Android應(yīng)用實例詳解的相關(guān)資料,需要的朋友可以參考下2017-05-05Java深入講解instanceof關(guān)鍵字的使用
instanceof 是 Java 的一個二元操作符,類似于 ==,>,< 等操作符。instanceof 是 Java 的保留關(guān)鍵字。它的作用是測試它左邊的對象是否是它右邊的類的實例,返回 boolean 的數(shù)據(jù)類型2022-05-05Python基礎(chǔ)之如何使用multiprocessing模塊
今天帶大家學(xué)習(xí)python多進(jìn)程的相關(guān)知識,文中對multiprocessing模塊的使用作了非常詳細(xì)的介紹,需要的朋友可以參考下2021-06-06解決java idea新建子目錄時命名不是樹形結(jié)構(gòu)的問題
這篇文章主要介紹了解決java idea新建子目錄時命名不是樹形結(jié)構(gòu)的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-08-08