java - Force BufferedWriter to write from BlockingQueue when another tasks finished -


i'm writing simple html parser jsoup. i've got 50 000 links check, thought it's great chance learn abut threads , concurnecy. i've got 8 tasks registered executorservice: 6 of them parse links data stored in arraylists , add blockingqueues. 2 of tasks filewriters based on bufferedwriter. problem when 6 tasks finish prase links, file writers stop write data blockingqueue, lose part of data. i'm pretty newbie in java, if give me hand.... code:

main file:

public static void main(string[] args) {     blockingqueue<arraylist<string>> units = new arrayblockingqueue<arraylist<string>>(50, true);     blockingqueue<arraylist<string>> subjects = new arrayblockingqueue<arraylist<string>>(50, true);     file subjectfile = new file("lekarze.csv");     file unitfile = new file("miejsca.csv");     executorservice executor = executors.newfixedthreadpool(9);     executor.submit(new thread(new filesaver(subjects, subjectfile)));     executor.submit(new thread(new filesaver(units, unitfile)));     for(int = 29323; < 29400; i++){         executor.submit(new parserdocsthread(i, subjects, units, errors));     }      executor.shutdown(); } 

filesaver class:

package parser;  import java.io.bufferedwriter; import java.io.file; import java.io.filewriter; import java.io.ioexception; import java.util.arraylist; import java.util.concurrent.blockingqueue;  public class filesaver implements runnable {     private blockingqueue<arraylist<string>> towrite = null;     private file outputfile = null;     private bufferedwriter writer = null;      public filesaver(blockingqueue<arraylist<string>> queue, file file){        towrite = queue;        outputfile = file;    }      public void run() {        try {           writer = new bufferedwriter(new filewriter(outputfile, true));           while(true){               try{                   save(towrite.take());               } catch(interruptedexception e) {                   e.printstacktrace();               }           }       } catch (ioexception e) {           e.printstacktrace();       }   }    private void save(arraylist<string> data){       string temp ="";       int size = data.size();       for(int = 0; < size; i++){           temp += data.get(i);           if(i != size - 1) temp += '\t';        }       try {           writer.write(temp);           writer.newline();       } catch (ioexception e) {           e.printstacktrace();       }   } } 

in parserdocsthread i'm use put() method add elements blockingqueue.

your consumer threads don't end cleanly because take() call waiting new array, , not closing buffered writer. serviceexecutor gives on waiting these threads finish, , kills them. causing last lines in writer not written out disk.

you should use poll(10, timeunit.seconds) (but appropriate timeout). after timeout, consumers give on producers, , should make sure close buffered writer last of buffer printed out properly.

try (bufferedwriter writer = new bufferedwriter(new filewriter(outputfile, true))) {     while(true){         list<string> data = towrite.poll(10, timeunit.seconds);         if (data == null) {            break;         }         save(data, writer);     } } catch (...) { } 

i've put buffered writer here try-with-resources (so try here automatically close writer) , passed save method, can way, , manually close writer in block if want:

try {     ... } catch(...) { } {     writer.close(); // closes , flushes out remaining lines } 

you may want put in call awaittermination on executor servier (like so: how wait threads finish, using executorservice?) wait time greater poll timeout.


Comments

Popular posts from this blog

javascript - Chart.js (Radar Chart) different scaleLineColor for each scaleLine -

apache - Error with PHP mail(): Multiple or malformed newlines found in additional_header -

java - Android – MapFragment overlay button shadow, just like MyLocation button -