1

Swingworker を使用して URL アドレスから値を要求し、表示される情報のバージョンを動的に変更しています。場合によっては、このワーカーはキャンセルされます。問題は、時々 java.lang.InterruptedException が発生することです (ただし、ワーカーをキャンセルするたびに発生するわけではありません)。どうすればいいのかわかりません。さらに、どこにスローされるのかわかりません。短時間で多くのバージョン変更を行うと取得されるため、デバッグできません(スライダーを使用しますが、これはスライダーをドラッグしているときに発生します)しばらくの間) 。すべて正常に動作しますが、次の厄介なエラーが発生します。

 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

プログラムがブラウザーでアプレットとして実行されている場合にのみ例外がスローされるという興味深いこと。プログラムが api からアプレットとして実行されている場合、例外はスローされません。

私のストリングワーカー:

    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());

}

}

何が原因で、どのように処理するか、または少なくとも非表示にする方法がわかりました(すべてが正常に機能するため)。どんな助けでも大歓迎です。

アップデート:

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;
}

残念ながら、システム アウト メッセージの代わりにスタック トレースが出力されます。ここで何が間違っているのでしょうか?

4

2 に答える 2

3

私の知る限り、他のスレッドがブロックされているスレッドをInterruptedException呼び出した場合にのみ発生します。Thread.interrupt()この場合、中断されたスレッドがwait()その時点で呼び出し中であったことは明らかです。

SwingWorker コードを見ると、スケジュールされたスレッドが呼び出しを決定すると、ワーカー スレッドが割り込みを受けるように見えますcancel(true)。ワーカー スレッドがその時点で何をしているかに応じて、 を取得するか、フラグが設定されInterruptedExceptionているだけの場合があります。Thread.interrupted

cancel(true)したがって、問題の解決策は、SwingWorkerインスタンスで何が呼び出されているかを調べることです。次に、それを行わないように変更するか、ワーカークラスがInterruptedException適切に処理するようにします。適切な動作は、おそらく例外をキャッチし、静かに戻ることです。call(...)

于 2012-07-05T10:44:37.860 に答える
2

私には、あなたが呼んでいるように見えますworker.cancel(true);(ワーカーがSwingWorkerであると仮定します)。はtrue、現在のスレッドが割り込み可能な状態にある場合、スレッドが割り込まれる可能性があることを示します。これが発生すると、スレッドが中断されたことを示す例外が自動的にスローされ、リソースを解放して何かを実行できるようになります。あなたの場合、これを無視して、開いているストリームを閉じることができると思います。

あなたの場合、あなたがあなたの「仕事」にどれだけいるかに応じて、タスクは中断されるかもしれませんし、されないかもしれません。

スレッドの中断について詳しくは、こちらをご覧ください。

于 2012-07-05T10:35:11.787 に答える