2014-03-06 190 views
0

這裏是我的代碼:線程,永遠不會結束

public class BigFileReader implements Runnable { 
    private final String fileName; 
    int a = 0; 

    private final BlockingQueue<String> linesRead; 
    public BigFileReader(String fileName, BlockingQueue<String> linesRead) { 
     this.fileName = fileName; 
     this.linesRead = linesRead; 
    } 
    @Override 
    public void run() { 
     try { 
      //since it is a sample, I avoid the manage of how many lines you have read 
      //and that stuff, but it should not be complicated to accomplish 
      BufferedReader br = new BufferedReader(new FileReader(new File("E:/Amazon HashFile/Hash.txt"))); 
      String str = ""; 

      while((str=br.readLine())!=null) 
      { 
       linesRead.put(str); 
       System.out.println(a); 
       a++; 
      } 

     } catch (Exception ex) { 
      ex.printStackTrace(); 
     } 

     System.out.println("Completed"); 
    } 
} 





public class BigFileProcessor implements Runnable { 
    private final BlockingQueue<String> linesToProcess; 
    public BigFileProcessor (BlockingQueue<String> linesToProcess) { 
     this.linesToProcess = linesToProcess; 
    } 
    @Override 
    public void run() { 
     String line = ""; 
     try { 
      while ((line = linesToProcess.take()) != null) { 
       //do what you want/need to process this line... 
       String [] pieces = line.split("(...)/g"); 
      } 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
} 





public class BigFileWholeProcessor { 
    private static final int NUMBER_OF_THREADS = 2; 
    public void processFile(String fileName) { 

     BlockingQueue<String> fileContent = new LinkedBlockingQueue<String>(); 
     BigFileReader bigFileReader = new BigFileReader(fileName, fileContent); 
     BigFileProcessor bigFileProcessor = new BigFileProcessor(fileContent); 
     ExecutorService es = Executors.newFixedThreadPool(NUMBER_OF_THREADS); 
     es.execute(bigFileReader); 
     es.execute(bigFileProcessor); 
     es.shutdown(); 

    } 
} 

此代碼是好的,但有一個主要的問題。也就是說,線程永遠不會結束!即使整個過程已經完成,我仍然可以保證程序還活着。這裏有什麼問題?

+3

你有什麼證據表明它永遠不會結束?你如何提交'Runnable'? –

+0

開始之前,setDeamon(true)。 – robermann

+1

與實際問題無關,但'a ++'[可能]不是線程安全的。您應該使用AtomicInteger代替。 – yshavit

回答

3
BlockingQueue.take()

將阻塞,直到元素可用:

獲取並移除此隊列的頭,如果需要的話,直到元素變得可用等待。

所以經過BigFileReader讀完輸入文件,並把在BlockingQueue的線條,BigFileProcessor將在新的輸入法take()永遠等待。

你可能想找到一種方法來通知BigFileProcessor會有沒有更多的投入不斷提上了BlockingQueue的,可能是通過增加a sentinel value到隊列或者找到一些其他的方式來告訴BigFileProcessor停止呼叫take()

的定點方法的一個例子:

public class BigFileReader implements Runnable { 
    public static final String SENTINEL = "SENTINEL"; //the actual value isn't very important 
    ... 

    while((str=br.readLine())!=null) { 
     linesRead.put(str); 
    } 
    //when reading the file is done, add SENTINEL to the queue 
    linesRead.put(SENTINEL); 
} 

//inside BigFileProcessor... 
while ((line = linesToProcess.take()) != null) { 
    // check if value in queue is sentinel value 
    if (line == BigFileReader.SENTINEL) { 
     //break out of the while loop 
     break; 
    } 
    //otherwise process the line as normal 
} 

另一種方法可以是使用the overload of poll that takes a timeout value代替take(),並具有邏輯是BigFileProcessor打破它的循環,如果它不能從隊列中讀什麼超過N秒等。

+0

這是我第一次處理這個問題。我不知道該怎麼做。你能告訴我嗎? –

+0

@GloryOfSuccess查看示例更新 –

+0

太好了。謝謝。 –

0

BlockingQueue顧名思義就是阻塞的。一旦你執行了queue.take(),線程就會掛起,直到隊列中有東西要佔用。爲了終止線程,您需要使用隊列.isEmpty()來知道隊列中是否還有消息。我建議您在完成讀取文件後發送文件結束消息,以便知道何時退出循環。

相關問題