multithreading - How to execute dependent tasks in Java 8 without any blocking -
not long ago answered question: executing dependent tasks in parallel in java using future.get() blocking current thread, , there possibility thread pool runs out of threads if many gets() called @ 1 time. how 1 compose futures futures in java?
i thought answer question myself, 1 can use completablefutures in java instead of futures. completablefutures allow composition via thencombine method, similiar scalas flatmap. there no blocking happening , 3 threads needed achieve fastest time.
import java.util.concurrent.completablefuture; import java.util.concurrent.executorservice; import java.util.concurrent.executors; import java.util.function.bifunction; import java.util.function.supplier; public class barrista { // number of threads used in executor static final int nothreads = 3; // time of each task static final int heatwater = 1000; static final int grindbeans = 1000; static final int frothmilk = 1000; static final int brewing = 1000; static final int combine = 1000; // method simulate work (pause current thread without throwing checked exception) public static void pause(long t) { try { thread.sleep(t); } catch(exception e) { throw new error(e.tostring()); } } // task heat water static class heatwater implements supplier<string> { @override public string get() { system.out.println("heating water"); pause(heatwater); return "hot water"; } } // task grind beans static class grindbeans implements supplier<string> { @override public string get() { system.out.println("grinding beans"); pause(grindbeans); return "grinded beans"; } } // task froth milk static class frothmilk implements supplier<string> { @override public string get() { system.out.println("frothing milk"); pause(frothmilk); return "some milk"; } } // task brew coffee static class brew implements bifunction<string,string, string> { @override public string apply(string groundbeans, string heatedwater) { system.out.println("brewing coffee " + groundbeans + " , " + heatedwater); pause(brewing); return "brewed coffee"; } } // task combine brewed coffee , milk static class combine implements bifunction<string,string, string> { @override public string apply(string frothedmilk, string brewedcoffee) { system.out.println("combining " + frothedmilk + " "+ brewedcoffee); pause(combine); return "final coffee"; } } public static void main(string[] args) { executorservice executor = executors.newfixedthreadpool(nothreads); long starttime = system.currenttimemillis(); try { // create tasks , let executor handle execution order completablefuture<string> frothmilk = completablefuture.supplyasync(new frothmilk(), executor); completablefuture<string> heatwaterfuture = completablefuture.supplyasync(new heatwater(), executor); completablefuture<string> grindbeans = completablefuture.supplyasync(new grindbeans(), executor); completablefuture<string> brew = heatwaterfuture.thencombine(grindbeans, new brew()); completablefuture<string> coffee = brew.thencombine(frothmilk, new combine()); // final coffee system.out.println("here coffee:" + coffee.get()); // analyzing times: system.out.println("\n\n"); system.out.println("actual time: \t\t\t\t" + (system.currenttimemillis() - starttime)/1000.0); // compute quickest possible time: long path1 = math.max(grindbeans, heatwater)+ brewing + combine; long path2 = frothmilk + combine; system.out.println("quickest time multi-threaded:\t\t" + math.max(path1, path2)/1000.0); // compute longest possible time: long longesttime = heatwater + grindbeans + frothmilk + brewing + combine; system.out.println("quickest time single-threaded thread:\t" + longesttime/1000.0); } catch (exception e) { e.printstacktrace(); } { executor.shutdown(); } } }
Comments
Post a Comment