SwingWorker スレッドで発生している恐ろしい例外をデバッグしようとしています。SwingWorker スレッドに名前を付けることができれば、受け取ったスタック トレースをより適切に解釈できます。
SwingWorker スレッドに名前を付けることができないようです (そうですか?)。コードにログステートメントを追加するだけでなく、ワーカースレッドを適切に識別するのに役立つベストプラクティスまたは「トリック」を探しています。
SwingWorker スレッドで発生している恐ろしい例外をデバッグしようとしています。SwingWorker スレッドに名前を付けることができれば、受け取ったスタック トレースをより適切に解釈できます。
SwingWorker スレッドに名前を付けることができないようです (そうですか?)。コードにログステートメントを追加するだけでなく、ワーカースレッドを適切に識別するのに役立つベストプラクティスまたは「トリック」を探しています。
SwingWorkerが使用しているThreadFactoryにアクセスできない場合でも、SwingWorkerが実行しているクラスのrun()またはcall()メソッドでThread.currentThread()。setName()を呼び出すことができます。
スレッドが実際にコードを実行しているときに、その値を設定していることを確認してください
SwingWorker によって使用される Thread は Executors.defaultThreadFactory からのものであり、これはプールからのものであることを意味します。したがって、「MyXYZThread」がスレッドの名前変更に失敗したシステム内の別の SwingWorker に再利用される場合、スレッドの名前付けは誤解を招く可能性があります。
SwingWorker を拡張して名前を含め、例外をスローするときにその名前をログに記録します。
注: 呼び出し元に例外処理の責任を負わせたくないのですが、SwingWorker の契約を変更せずにそれを行う方法がわかりません。
private static abstract class MySwingWorker<X, Y> extends SwingWorker<X, Y>
{
private final String taskName;
public MySwingWorker(String name)
{
this.taskName = name;
}
public String getTaskName() {
return taskName;
}
}
使用法:
new MySwingWorker<Object,Object>("my task") {
protected Object doInBackground() {
try {
return someCall();
}
catch(Exception e) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE,
"Exception in " + getTaskName(), e);
throw e;
}
}
}.execute();
リフレクションを使用してスレッドを取得し、setName も呼び出すことができるはずです。これを行うには setAccessible メソッドを使用する必要があり、アクセスする必要がある変数の名前を見つけるために掘り下げる必要があります。
私はこの方法を好みませんが、他の方法と同じくらい「ハック」かもしれません...
ベスト プラクティスは、前述の Thread.currentThread().setName(String) を使用することです。
「トリック」は、SwingWorkers の ThreadFactory を設定することです。
sun.awt.AppContext context = sun.awt.AppContext.getAppContext();
int maxWorkers = 10;
ThreadFactory factory = ...
ExecutorService executor = Executors.newFixedThreadPool(maxWorkers, factory);
context.put(SwingWorker.class, executor);
これは、sun.awt パッケージのクラスを使用しているため、警告されています。