Wednesday 15 July 2015

concurrency - Java 8 parallel forEach progress indication -



concurrency - Java 8 parallel forEach progress indication -

for performance reason utilize foreach loop of parallel lambda stream in order process instance of collection in java. runs in background service utilize updateprogress(double,double) method in order inform user current progress.

in order indicate current progress need progress indicator in form of integer counter. however, not possible can access final variables within lambda expression.

code illustration see below, collection place holder possible instance of collection:

int progress = 0; collection.parallelstream().foreach(signer -> { progress++; updateprogress(progress, collection.size()); });

i'm aware can solve problem using simple for-loop. however, performance reason nice solve in way.

does know more or less neat solution this?

as proposed markspace, using atomicinteger solution:

atomicinteger progress = new atomicinteger(); collection.parallelstream().foreach(signer -> { progress.incrementandget(); // usefull work

});

i not utilize runlater() variant goal high performance, , if many parallel threads generte javafx 'runlater' tasks, 1 time again create bottleneck...

for same reason not phone call update progressbar each time, utilize seaparte javafx timeline update progress bar in regular intervals independently processing threads.

here total code comparing sequential , parallel processing progressbar. if remove sleep(1) , set number of items 10 1000000 still work concurrently , efficiently...

public class parallelprogress extends application { static class parallelprogressbar extends progressbar { atomicinteger mydonecount = new atomicinteger(); int mytotalcount; timeline mywhatcher = new timeline(new keyframe(duration.millis(10), e -> update())); public void update() { setprogress(1.0*mydonecount.get()/mytotalcount); if (mydonecount.get() >= mytotalcount) { mywhatcher.stop(); mytotalcount = 0; } } public boolean isrunning() { homecoming mytotalcount > 0; } public void start(int totalcount) { mydonecount.set(0); mytotalcount = totalcount; setprogress(0.0); mywhatcher.setcyclecount(timeline.indefinite); mywhatcher.play(); } public void add(int n) { mydonecount.addandget(n); } } hbox testparallel(hbox box) { arraylist<string> mytexts = new arraylist<string>(); (int = 1; < 10000; i++) { mytexts.add("at "+system.nanotime()+" ns"); } button runp = new button("parallel"); button runs = new button("sequential"); parallelprogressbar progress = new parallelprogressbar(); label result = new label("-"); runp.setonaction(e -> { if (progress.isrunning()) return; result.settext("..."); progress.start(mytexts.size()); new thread() { public void run() { long ms = system.currenttimemillis(); mytexts.parallelstream().foreach(text -> { progress.add(1); seek { thread.sleep(1);} grab (exception e1) { } }); platform.runlater(() -> result.settext(""+(system.currenttimemillis()-ms)+" ms")); } }.start(); }); runs.setonaction(e -> { if (progress.isrunning()) return; result.settext("..."); progress.start(mytexts.size()); new thread() { public void run() { final long ms = system.currenttimemillis(); mytexts.foreach(text -> { progress.add(1); seek { thread.sleep(1);} grab (exception e1) { } }); platform.runlater(() -> result.settext(""+(system.currenttimemillis()-ms)+" ms")); } }.start(); }); box.getchildren().addall(runp, runs, progress, result); homecoming box; } @override public void start(stage primarystage) throws exception { primarystage.settitle("progressbar's"); hbox box = new hbox(); scene scene = new scene(box,400,80,color.white); primarystage.setscene(scene); testparallel(box); primarystage.show(); } public static void main(string[] args) { launch(args); } }

java concurrency lambda javafx

No comments:

Post a Comment