2014-12-11 28 views
1

我必須實現一個存儲有關某個學校項目的機場信息的類。該班級應該讀取我們的講師向我們提供的用HTML編寫的網站上的航班和乘客信息的數據,爲了做到這一點,我們正在使用線程。我的問題是,當我在我的線程上調用start()方法時,它不會調用實現runnable的類的run方法,這很奇怪,因爲當我第一次測試程序並直接調用run()方法時,它工作得很好。這是在我的工人類的run方法內執行實際數據處理的while循環。運行方法有效,但線程不會調用它

while (1 == 1) { 
    temp = scan.next(); 
    if ((temp.equals("</body>"))) 
     break; 
    else { 
     name = temp; 
     flightNum = scan.nextInt(); 
     city = scan.next(); 
     indexOfBR = city.indexOf("<"); 
     city = city.substring(0, indexOfBR); 

     synchronized (airplanes) { 
      addFlight(flightNum, city); 
      addPassengerReservation(flightNum, name); 
     } 
    } 
} 
scan.close(); 

循環應該讀乘客的名字,然後一個航班號,然後目的地城市,存儲在HTML文件中:

"passenger name" "flight Number" "destination city"<br> 

創建並運行線程

的方法
public void readFlightData(String[] urls) { 
    for (int x = 0; x < urls.length; x++) { 
     if (!(urls[x].equals(""))) { 
      try { 
       Worker w = new Worker(new URL(urls[x])); 
       Thread work = new Thread(w); 
       work.start(); 
      } 
      catch (MalformedURLException e) { 
       //do nothing 
      } 
     } 
    } 
} 

當我在工作線程上調用start並且我不知道爲什麼時,此方法不調用run方法。任何幫助將不勝感激

我已經確定問題爲while循環中的同步塊。傳遞給同步塊飛機的對象是一個ArrayList,用於存放機場班級中的航班和乘客信息。 addFlight()方法旨在添加一個包含flightNum和目標城市的航班。 addPassengerReservation爲名稱爲「name」的指定flightNum添加一位乘客

+1

是行'工作=新線程(W);'實際上運行?也許你應該記錄下'MalformedURLException',以便知道它發生了。 – 2014-12-11 04:04:59

+0

我回去做了。線程正在運行。或者至少,代碼沒有拋出MalformedURLException。另外,當我通過直接調用w.run()來運行代碼時,它運行正常,並且我現在使用的是同一個url。 – Nick 2014-12-11 04:30:55

+0

只是爲了說明,儘管有'while(1 == 1)',你也可以直接寫'while(true)'來創建一個無限循環。 – gprathour 2014-12-11 04:31:34

回答

1

代碼非常脆弱。我建議進行以下更改。我認爲有一個MalformedURLException,你隱藏它。

public void readFlightData(String[] urls) { 
    for (int x = 0; x < urls.length; x++) { 
     if (!(urls[x].equals(""))) { 
      try { 
       Worker w = new Worker(new URL(urls[x])); 
       Thread work = new Thread(w); 
       work.start(); 
      } 
      catch (MalformedURLException e) { 
       System.err.print(e); 
      } 
     } 
    } 
} 
+0

我做了這些更改並且代碼沒有拋出錯誤,但是,它仍然不起作用。在調用線程實例化的對象的run方法之前,start方法中究竟發生了什麼?也許這可能會導致問題。 – Nick 2014-12-11 05:54:34

+0

而不是多個網址,你可以嘗試運行一個網址的線程?這將與您的單一執行類似。 – 2014-12-11 05:58:20

+0

這就是我現在正在測試它。 urls []只有一個元素 – Nick 2014-12-11 06:05:39

0

我想通了。我的問題是,在完成運行我創建的線程並下載必要的信息之前,我正在調用機場類中的方法。我不得不在所有線程上調用join()來解決這個問題。對於那些古怪的人,這裏是工作代碼:

ArrayList<Thread> threads = new ArrayList<Thread>(); 
int x; 

for (x = 0; x < urls.length; x++) { 
    if (!(urls[x].equals(""))) { 
     try { 
      Worker w = new Worker(new URL(urls[x])); 
      Thread work = new Thread(w); 
      work.start(); 
      threads.add(work); 
     } 
     catch (MalformedURLException e) { 
      System.err.print(e); 
     } 
    } 
} 

for (x = 0; x < threads.size(); x++) 
    try { 
     threads.get(x).join(); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
} 
+0

恭喜你自己解決了這個問題。但是,如何調用與'run()'相關的'join'?順便說一句。您應該通過重新設置線程上的中斷標誌或拋出InterruptedException來修復對InterruptedException的處理。 「Brian Goetz」描述了處理InterruptedExceptions或者甚至在這篇博客文章中的策略[Java理論與實踐:處理InterruptedException](原文:http://www.ibm.com/developerworks/library/j-jtp05236/) – andih 2014-12-12 05:55:31

+0

事實證明,該線程實際上是調用運行,但是,我只是沒有通過我的測試意識到這一點,因爲在我創建的線程完成下載所有必要信息之前,我調用的Junit測試已完成運行。這導致了昨天讓我感到困擾的錯誤。通過在創建線程的方法中調用join,我可以有效地阻止方法結束,並停止運行Junit測試,直到所有線程完成下載其信息。 – Nick 2014-12-12 06:00:03

相關問題