java - CopyOnWriteArrayList iteration inconsistancy with multithreading? -


i'm sending batches of strings in copyonwrite arraylists executorservice processed in parallel, runnable task processing these lists need iterate on list , processing on each string.

after running issues concurrency regular arraylists, tried use copyonwritearraylists because they're thread-safe, results inconsistent. is, different results on every run of program, suggesting contents of arraylist changed in way before each runnable taks can iterate on it.

public static class batchrunnable implements runnable {      private copyonwritearraylist<string> batch;      batchrunnable(copyonwritearraylist<string> batch){         this.batch = batch;     }      @override     public void run(){         //iterate on batch , work string elements         //make no modifications batch     } } 
  • the runnable task makes no modifications arraylist, iterates on list , uses string elements of list processing.

  • the place in copyonwritearraylist changed @ instantiation each new runnable task.

when passing in single strings instead of batching, had consistent , correct results, when began use batches in string arraylists, got inconsistent results, suggesting compromising concurrency of copyonwritearraylist batch, despite being supposedly thread-safe.

any appreciated, thanks!

edit: here batches being constructed:

        runnable worker = null;         while((line = br.readline()) != null) {             recordbatch.add(line);             if(recordbatch.size() == 100){                 worker = new batchrunnable(recordbatch);                 executor.execute(worker);                 recordbatch.clear();             }          }                    executor.shutdown();         executor.awaittermination(60,timeunit.seconds);   

look while loop:

while((line = br.readline()) != null) {         recordbatch.add(line);         if(recordbatch.size() == 100){             worker = new batchrunnable(recordbatch);             executor.execute(worker);             recordbatch.clear();         }      }   

you passing reference same list in batchrunnable. so, change list @ 1 place, reflected in reference. so, once clear list using recordbatch.clear(), list empty references, 1 having in batchrunnable. why getting inconsistent result.

you should pass copy of recordbatch list in batchrunnable:

worker = new batchrunnable(new arraylist<string>(recordbatch)); 

Comments

Popular posts from this blog

javascript - Laravel datatable invalid JSON response -

java - Exception in thread "main" org.springframework.context.ApplicationContextException: Unable to start embedded container; -

sql server 2008 - My Sql Code Get An Error Of Msg 245, Level 16, State 1, Line 1 Conversion failed when converting the varchar value '8:45 AM' to data type int -