并行流與串行流
10年積累的成都做網(wǎng)站、成都網(wǎng)站制作、成都外貿(mào)網(wǎng)站建設(shè)經(jīng)驗(yàn),可以快速應(yīng)對(duì)客戶對(duì)網(wǎng)站的新想法和需求。提供各種問題對(duì)應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識(shí)你,你也不認(rèn)識(shí)我。但先網(wǎng)站設(shè)計(jì)后付款的網(wǎng)站建設(shè)流程,更有云夢(mèng)免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。
并行流就是把一個(gè)內(nèi)容分成多個(gè)數(shù)據(jù)塊,并用不同的線程分別處理每個(gè)數(shù)據(jù)塊的流。
java 8 中將并行進(jìn)行了優(yōu)化,我們可以很容易的對(duì)數(shù)據(jù)進(jìn)行并行操作。Stream API 可以聲明性地通過 parallel()與 sequential()在并行流與順序流之間進(jìn)行切換。
了解 Fork/Join 框架
Fork/Join 框架:就是在必要的情況下,將一個(gè)大任務(wù),進(jìn)形拆分(fork)成若干個(gè)小任務(wù)(拆到不可再拆時(shí)),再將一個(gè)個(gè)的小任務(wù)運(yùn)行的結(jié)果進(jìn)行join匯總。
Fork/Join 框架與傳統(tǒng)線程池的區(qū)別:
采用“工作竊取”模式(work-stealing):
當(dāng)執(zhí)行新的任務(wù)時(shí),它可以將其拆分成更小的任務(wù)執(zhí)行,并將小任務(wù)加到線程隊(duì)列中,然后再?gòu)囊粋€(gè)隨機(jī)線程的隊(duì)列中偷一個(gè)并把它放在自己的隊(duì)列中。
相對(duì)于一般的線程池實(shí)現(xiàn),fork/join框架的優(yōu)勢(shì)體現(xiàn)在對(duì)其中包含的任務(wù)的處理方式上.在一般的線程池中,如果一個(gè)線程正在執(zhí)行的任務(wù)由于某些原因無法繼續(xù)運(yùn)行,那么該線程會(huì)處于等待狀態(tài).而在fork/join框架實(shí)現(xiàn)中,如果某個(gè)子問題由于等待另外一個(gè)子問題的完成而無法繼續(xù)運(yùn)行.那么處理該子問題的線程會(huì)主動(dòng)尋找其他尚未運(yùn)行的子問題來執(zhí)行.這種方式減少了線程的等待時(shí)間,提高了性能。
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("消耗時(shí)間"+Duration.between(start, end).toMillis()+"ms");//消耗時(shí)間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("消耗時(shí)間" + Duration.between(start, end).toMillis()+"ms");//消耗時(shí)間2418ms } } class ForkJoinCalculate extends RecursiveTask<Long>{ private static final long serialVersionUID = 1234567890L;//序列號(hào) 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) 是一個(gè)容器類,代表一個(gè)值存在或不存在。
原來用null表示一個(gè)值不存在,現(xiàn)在 Optional可以更好的表達(dá)這個(gè)概念。并且可以避免空指針異常。
常用方法:
Optional.of(T t) : 創(chuàng)建一個(gè) Optional 實(shí)例
Optional.empty() : 創(chuàng)建一個(gè)空的 Optional 實(shí)例
Optional.ofNullable(T t):若 t 不為 null,創(chuàng)建 Optional 實(shí)例,否則創(chuàng)建空實(shí)例
isPresent() : 判斷是否包含值
orElse(T t) : 如果調(diào)用對(duì)象包含值,返回該值,否則返回t
orElseGet(Supplier s) :如果調(diào)用對(duì)象包含值,返回該值,否則返回 s 獲取的值
map(Function f): 如果有值對(duì)其處理,并返回處理后的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); } //需求:獲取一個(gè)男人心中女神的名字 public String getGodnessName(Man man){ if(man!=null){ Godness g=man.getGod(); if(g!=null){ return g.getName(); } } return "蒼老師"; } //運(yùn)用Optional的實(shí)體類 @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框架使用心得的全部?jī)?nèi)容,大家在學(xué)習(xí)的時(shí)候如果還有任何不明白的地方可以在下方的留言區(qū)討論。
網(wǎng)頁題目:java8中forkjoin和optional框架使用
鏈接地址:http://aaarwkj.com/article8/gppsop.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供全網(wǎng)營(yíng)銷推廣、移動(dòng)網(wǎng)站建設(shè)、做網(wǎng)站、品牌網(wǎng)站設(shè)計(jì)、關(guān)鍵詞優(yōu)化、網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)