2013-09-23 109 views
0

我有一個運行方法,啓動一個新的線程,並希望在它結束後啓動另一個方法,但這是行不通的。在方法結束時,我放了一些打印輸出語句,它們只顯示幾次,比如我第一次加載Java程序時。通常他們不顯示。爲什麼在打印輸出結束運行方法不打印

我想知道他們爲什麼沒有顯示出來,它有一個可靠的方法,像一個回調方法,比如我可以在Java線程上使用的AsyncTask的onPostExecute()。

不知道爲什麼打印輸出報表不顯示98%的時間。有任何想法嗎?

這裏有點困惑。因爲我認爲文件會在while循環中達到結尾和count變量,並且它將變爲0或-1,那麼while循環會結束並執行進程,並且它將退出while循環並繼續線程。這沒有發生,它沒有任何意義。

我用這段代碼收到的文件是完整的,沒有問題。但是我需要啓動另一個線程方法來將消息發送回Android客戶端,告訴它文件已成功接收。

代碼

@Override 
public void run() { 

    FileOutputStream fos = null; 
    BufferedOutputStream bos = null; 
    BufferedInputStream bis = null; 
    DataInputStream dis = null; 
    int bufferSize = 0; 

    File file = new File("/Users/UserName/sampleFile.db"); 

    // get input streams 
    try { 
    fos = new FileOutputStream(file); 
    bos = new BufferedOutputStream(fos); 
    bis = new BufferedInputStream(socket.getInputStream()); 
    dis = new DataInputStream(bis); 
    } catch (IOException ex) { 
     Logger.getLogger(MultiThreader.class.getName()).log(Level.SEVERE, null, ex); 
    } 

    try { 
     bufferSize = socket.getReceiveBufferSize(); 
    } catch (SocketException ex) { 
     Logger.getLogger(MultiThreader.class.getName()).log(Level.SEVERE, null, ex); 
    } 

    int fileSizeFromClient = 0; 
    long serialNumber = 0; 

    try { 
     fileSizeFromClient = dis.readInt(); 
     serialNumber = dis.readLong(); 
    } catch (IOException ex) { 
     Logger.getLogger(MultiThreader.class.getName()).log(Level.SEVERE, null, ex); 
    } 

    String serialString = String.valueOf(serialNumber); 

    System.out.println("filesize " + fileSizeFromClient); 
    System.out.println("serialNumber " + serialString); 
    System.out.println("bufferSize " + bufferSize); 

    int count = 0; 
    try { 
     bos.flush(); 
    } catch (IOException ex) { 
     Logger.getLogger(MultiThreader.class.getName()).log(Level.SEVERE, null, ex); 
    } 

    byte[] buffer = new byte[fileSizeFromClient]; 
    try { 
     while((count = dis.read(buffer)) > 0){ 
      bos.write(buffer, 0, count); 

      if(count == -1){ // <-- this line does not help break out of loop 
      break; 
      } 


     } 

     System.out.println("size of file written " + buffer.length); // <-- does not print out 
     socket.close(); 

     System.out.println("test out 1"); // <-- does not print out 

    } catch (IOException ex) { 
     Logger.getLogger(MultiThreader.class.getName()).log(Level.SEVERE, null, ex); 

    } catch (Exception ex) { 
      Logger.getLogger(MultiThreader.class.getName()).log(Level.SEVERE, null, ex); 
     } 

    System.out.println("test out 2"); // <-- does not print out 

} // end run 

編輯的休息:忘了提,這是一個Java桌面應用程序,而不是機器人,但它連接到客戶端是一個Android設備。發送和接收任何文件沒有問題,socket和TCP/IP文件聯網沒有問題

+0

你有參考你正在啓動的線程嗎?我有一個與C#類似的問題,因爲我沒有保留一個引用線程垃圾收集... – Leon

+1

' while(count ...> 0)'使得'if'死代碼,從來沒有成功。並且'bos.close()'已經做了'fos.close()'(對於bis是相同的)。 –

+0

通過引用你的意思是線程變量?每次建立新的套接字連接時,此線程都由另一個類發起,就像這樣; MultiThreader multi = new MultiThreader(socket); 線程t =新線程(多); t.start(); – Kevik

回答

2

我找到了問題的答案。

Java服務器被卡住或掛在這條線:

while((count = dis.read(buffer)) > 0){ 
     bos.write(buffer, 0, count); 

,因爲在Android客戶端的服務器連接到OutputStream對象的。如果您關閉OutputStream的客戶端這樣的:

dos.close(); // for DataOutputStream dos; 

在客戶端的InputStream對象沒有任何影響,它只是爲OutputStream。如果客戶端中的OutputStream在for循環後立即關閉,那麼它將停止Java Sever在for循環中的阻塞或掛起。來自Android客戶端

while ((count = bis.read(bytes)) > 0) { 
      dos.write(bytes, 0, count); 
     } 
      dos.close(); 

代碼調整過後,都在Java中的System.out.println語句的切斷後的for循環現在的工作。一直是run方法的最後一行。