lambda - From Java parallelstream spawns other parallelStreams and fails seldom -


considering following function:

public void execute4() {         file filepath = new file(filepathdata);         file[] files = filepath.listfiles((file filepathdata) -> filepathdata.getname().endswith("cdr"));         list<cdr> cdrs = new arraylist<cdr>();         arrays.aslist(files).parallelstream().foreach(file -> readcdrp(cdrs, file));         cdrs.sort(cdrsorter);     } 

which reads list of files containing cdr , executes readcdrp() this:

private void readcdrp(list<cdr> cdrs, file file) {     final cdr cdr = new cdr(file.getname());     try (bufferedreader bfr = new bufferedreader(new filereader(file))) {         list<string> lines = bfr.lines().collect(collectors.tolist());         lines.parallelstream().foreach(e -> {             string[] data = e.split(",", -1);             cdrentry entry = new cdrentry(file.getname());             (int = 0; < data.length; i++) {                 entry.setfield(i, data[i]);             }             cdr.addentry(entry);         });          if (cdr != null) {             cdrs.add(cdr);         }     } catch (ioexception e) {         e.printstacktrace();     } } 

what observe , not time, either arrayindexnotbound exception @ readcdrp function on line (which awkward, list of cdr arraylist() ):

cdr.addentry(entry); 

or @ last line in execute4() apply sorting.

i think issue first parallelstream execute4 not in separate space in memory second parallelstream execution inside readcdrp() , seems share wrongly data. using "seem" word can't confirm , hutch.

the questions are: code buggy bone jdk8 perspective? there workaround using same flow, using countdownlatch example? limitation of forkjoinpool ?

thanks responce....

edit(1): addentry part of class itself:

class cdr {         public final string filename;         private final list<cdrentry> entries = new arraylist<cdrentry>();          public cdr(string filename) {             super();             this.filename = filename;         }          public list<cdrentry> getentries() {             return entries;         }          public list<cdrentry> addentry(cdrentry e) {             entries.add(e);             return entries;         }          public string getfilename() {             return this.filename;         }     } 

when starting programming in functional style should prefer immutable objects can created via construction (or using builder pattern or factory method). cdrentry class may this:

class cdrentry {     private final string[] fields;     private final string name;      public cdrentry(string name, string[] fields) {         this.name = name;         this.fields = fields;     }     // add getters , whatever } 

and cdr class may this:

class cdr {     private final string filename;     private final list<cdrentry> entries;      public cdr(string filename, list<cdrentry> entries) {         this.filename = filename;         this.entries = entries;     }      public list<cdrentry> getentries() {         return entries;     }      public string getfilename() {         return this.filename;     } } 

having such classes things become easier. rest of code can rewritten this:

public void execute4() {     file filepath = new file(filepathdata);     file[] files = filepath.listfiles((file data, string name) ->               data.getname().endswith("cdr")); // fixed line: had compilation error     list<cdr> cdrs = arrays.stream(files).parallel()             .map(this::readcdrp).sorted(cdrsorter)             .collect(collectors.tolist()); }  private cdr readcdrp(file file) {     try (bufferedreader bfr = new bufferedreader(new filereader(file))) {         // i'm not sure collecting lines list          // before main processing necessary         return bfr.lines().parallelstream()                 .map(e -> new cdrentry(file.getname(), e.split(",", -1)))                 .collect(collectors.collectingandthen(                         collectors.tolist(), list -> new cdr(file.getname(), list)));     } catch (ioexception e) {         throw new uncheckedioexception(e);     } } 

in general remember foreach not cleanest way solve tasks. may helpful when integrate streams legacy code, in general should avoided.


Comments