2012-07-05 38 views
1

我正在使用Swingworker從url地址請求值以動態更改所顯示信息的版本。在某些情況下,這名工人被取消。問題是我有時會得到java.lang.InterruptedException(但不是每次我取消worker時)。我不知道該如何處理它,而且我也不知道它在哪裏拋出,我無法調試它,因爲我在短時間內進行大量版本更改時得到它(我使用滑塊,並且在拖動它時發生這種情況一段時間)。一切工作正常,但我得到這個惱人的錯誤:java.lang.InterruptedException使用swingworker

java.lang.InterruptedException 
at java.lang.Object.wait(Native Method) 
at sun.plugin2.message.Queue.waitForMessage(Unknown Source) 
at sun.plugin2.message.Pipe$2.run(Unknown Source) 
at com.sun.deploy.util.Waiter$1.wait(Unknown Source) 
at com.sun.deploy.util.Waiter.runAndWait(Unknown Source) 
at sun.plugin2.message.Pipe.receive(Unknown Source) 
at sun.plugin2.main.client.MessagePassingExecutionContext.doCookieOp(Unknown Source) 
at sun.plugin2.main.client.MessagePassingExecutionContext.getCookie(Unknown Source) 
at sun.plugin2.main.client.PluginCookieSelector.getCookieFromBrowser(Unknown Source) 
at com.sun.deploy.net.cookie.DeployCookieSelector.getCookieInfo(Unknown Source) 
at com.sun.deploy.net.cookie.DeployCookieSelector.get(Unknown Source) 
at sun.net.www.protocol.http.HttpURLConnection.setCookieHeader(Unknown Source) 
at sun.net.www.protocol.http.HttpURLConnection.writeRequests(Unknown Source) 
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source) 
at org.dbwiki.web.applet.ValueRequester.doInBackground(ValueRequester.java:40) 
at org.dbwiki.web.applet.ValueRequester.doInBackground(ValueRequester.java:1) 
at javax.swing.SwingWorker$1.call(Unknown Source) 
at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source) 
at java.util.concurrent.FutureTask.run(Unknown Source) 
at javax.swing.SwingWorker.run(Unknown Source) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) 
at java.lang.Thread.run(Unknown Source) 

而且之後每一個上面附加的消息顯示異常被拋出:

sun.plugin2.main.client.PluginMain: unrecognized message ID 46 

有趣的事情是例外程序在運行時才拋出瀏覽器作爲一個applet,如果程序從api作爲applet運行,則不會引發異常。

我StringWorker:

package org.dbwiki.web.applet; 

import java.io.BufferedReader; 
import java.io.InputStreamReader; 
import java.net.URL; 
import java.net.URLConnection; 
import java.util.ArrayList; 
import javax.swing.SwingWorker; 

public class ValueRequester extends SwingWorker<Void, Void> { 
    HtmlGenerator htmlGen; 
    ArrayList<String[]> versionsData; 
    String id; 
    private String dbName; 
    ValueRequester (HtmlGenerator htmlGen, ArrayList<String[]> versionData, int ver){ 
    try { 
     this.htmlGen=htmlGen; 
     if (TreeVisualiser.typeParameter.equals(TreeVisualiser.StructureVisualiserParameter)) 
      this.id=htmlGen.getElem().getVersionElementId(ver); 
     else if(TreeVisualiser.typeParameter.equals(TreeVisualiser.HistoryVisualiserParameter)) 
      this.id=htmlGen.getElem().getId(); 
     this.dbName=htmlGen.getElem().getDBName(); 
     this.versionsData=versionData; 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

    } 
    protected Void doInBackground() throws Exception { 
    try{ 
     String value=""; 
     URL historyURL = new URL("http://127.0.0.1:8080/"+dbName+id+"?value"); 
     URLConnection hc = historyURL.openConnection();  
     BufferedReader in = new BufferedReader(new InputStreamReader(hc.getInputStream())); 
     String line; 
     while ((line = in.readLine()) != null) { 
      value+=line; 
     } 
     in.close(); 

     this.htmlGen.formDisplayerHead(); 
     this.htmlGen.formNodeDataHtml(value,this.versionsData); 
     this.htmlGen.formDisplayerTail(); 
    } 
    catch(Exception e) 
    { 
     e.printStackTrace(); 
    } 
     return null; 
} 

protected void done() 
{ 
    if (!this.isCancelled()) 
    this.htmlGen.dataDisplayer.setText(this.htmlGen.getHtml()); 

} 

} 

我現在的想法是什麼原因呢,該如何處理呢,或者至少如何隱藏它(因爲一切正常)。任何幫助,將不勝感激。

UPDATE:

我試圖抓住這個異常的ValueRequester.doInBackround(),但我的catch語句不捕獲異常。我更新doInBackground()的代碼:

protected Void doInBackground() throws Exception { 
     try{ 
      String value=""; 
      URL historyURL = new URL("http://127.0.0.1:8080/"+dbName+id+"?value"); 

      URLConnection hc = historyURL.openConnection(); 
      InputStream inputStrm=hc.getInputStream(); 
      InputStreamReader inputStrmRdr= new InputStreamReader(inputStrm); 
      this.in = new BufferedReader(inputStrmRdr); 
      String line; 
      while ((line = in.readLine()) != null) { 
       value+=line; 
      } 
      this.htmlGen.formDisplayerHead(); 
      this.htmlGen.formNodeDataHtml(value,this.versionsData); 
      this.htmlGen.formDisplayerTail(); 
     }catch (InterruptedException e){ 
      System.out.println("Interrupted Exception caught!"); 
      // e.printStackTrace(); 
     } 

    return null; 
} 

不幸的是堆棧跟蹤還是印刷的,而不是我的系統出的消息。任何想法在這裏可能是錯的?

+0

悄悄返回這不是完整的堆棧跟蹤,是嗎?實際上你得到的是由此InterrupedException導致的IOException,對吧? – 2012-07-05 10:34:09

回答

2

據我所知,一個InterruptedException只發生,如果其他線程調用Thread.interrupt()被阻止的線程上。在這種情況下,顯然中斷的線程當時在撥打wait()

看着SwingWorker代碼,看起來如果被調度的線程決定調用cancel(true),工作線程會得到一箇中斷。根據工作線程當時正在執行的操作,它可能會得到InterruptedException,或者它可能只設置了其Thread.interrupted標誌。

因此,您的問題的解決方案似乎是要找出SwingWorker實例上調用cancel(true)的內容。然後要麼改變它不這樣做......或者讓你的工人階級適當地處理InterruptedException。適當的行爲可能會發現異常並悄然從call(...)

+0

即使我刪除了我的帖子在這裏[我認爲只有得到()返回異常](http://stackoverflow.com/questions/7053865/cant-get-arrayindexoutofboundsexception-from-future-and-swingworker-if-threa)和不像你所描述的那樣'只有在其他線程調用時纔會出現',所有從SwingWorker調用的東西都沒有直接返回異常 – mKorbel 2012-07-05 13:27:10

+0

@mKorbel - 我知道你在說什麼,在某種意義上你是對的。但問題不在於拋出'get()'的異常。看看堆棧跟蹤。 – 2012-07-05 14:02:04

+0

同意,每一個我看到,這隻可能從創建一個新的對象作爲局部變量,也許可能是錯誤的想法/錯誤在SwingWorker內創建這些對象(對象可以創建之前)或使用SwingWorker在所有類型的後臺任務 – mKorbel 2012-07-05 15:30:25

2

對我來說,你看起來像你打電話worker.cancel(true);(假設工人是你的SwingWorker)。 true表示如果當前的線程處於可中斷狀態,線程可以被中斷。發生這種情況時,它會自動拋出一個異常,指示線程已被中斷,從而允許您釋放資源並可能執行某些操作。我想在你的情況下,你可以放心地忽略這一點,只需關閉打開的流。

就你的情況而言,根據你在「工作」中的距離有多遠,任務可能會被中斷。

有關Thread interruption here的詳細信息,請參見。