(以下の編集を必ずお読みください。この質問は明らかに混乱を招きます。申し訳ありません)
典型的なSwingUtilities.invokeLater
呼び出しは次のとおりです。
SwingUtilities.invokeLater( new Runnable() {
public void run() {
...
}
} );
今、私は何になるかを知りたいSwingUtilities.invokeNowOrLaterIfEDT
です。
もちろん、次のような独自のユーティリティクラスを使用することもできます。
public static void invokeNowOrLaterIfEDT( @NotNull Runnable r ) {
if ( SwingUtilities.isEventDispatchThread() ) {
Thread t = new Thread( r );
t.start();
} else {
r.run();
}
}
ただし、これには、EDTから呼び出されるたびに新しいスレッドが作成されるという欠点があります(そして、その新しいスレッドがスケジュールされるのを待つ必要があります)。
これを行う別の方法は、アプリのライフサイクル中に実行されている1つの追加スレッド(遅延インスタンス化される可能性があります)を使用して、ブロッキングキューを使用してをエンキューすることRunnables
です。利点は、EDTからそのようなメソッドを呼び出すたびにスレッドが常に作成されるとは限らないことです。
このようなものがデフォルトのJavaAPIに存在しますか?
上記の例のように、EDTから呼び出されるたびに新しいスレッドを作成するかRunnables
、EDTの外部で実行されるスレッドを1つ追加するだけで、キューに入れられますか?
編集:EDTから呼び出される場合と呼び出されない場合と同様SwingUtilities.invokeLater
に、私が考えていたメソッドはEDTから呼び出される場合と呼び出されない場合があります。GUI / EDTでのユーザーアクションからトリガーされる場合とされない場合がある、完全に非同期の何かを実行することです。SwingUtilities.invokeLater
EDTを使用しているかどうかに関係なく、EDTを呼び出すときに気にせずに、EDTで何かを実行できると非常に便利だと思います。invokeNowOrLaterIfEDT(...)
そして、上で示したものはとても便利だと思います。しかし、私はそれについて誤解されているかもしれません。そのような方法の必要性は狂っていますか?今、私は疑い始めています!?
編集2:私はまったくはっきりしていません、そして私はそれを理解します、それについて申し訳ありません。EDTからではなく非同期で実行したいのは、非常に長いプロセスではなく、プログレスバーや何が起こっているかを示すものなどの更新は必要ありません。シングルスレッド/キューに入れられている場合も問題ありません(明らかに、質問で述べました)。さまざまなコアなどに負荷を効率的に分散するためのスレッドプールをまったく求めていません。これらはEDTで実行する必要がなく、EDTから呼び出されるかどうかに関係なく、小さな計算であるだけです。これは、EDTの外部で実行したい非常に小さな非同期のものです。それらがすべて同じスレッドなどでキューに入れられている場合は問題ではありません。
しかし今、あなたの答えのおかげで、そのようなものが単一のスレッドと実行可能なキューを使用して実装された場合、長い計算のためにそのようなユーティリティメソッドを呼び出すことによって足で自分自身を撃つことは非常に簡単であることもわかりますその後、正しくマルチスレッド化されるのではなく、すべてがキューに入れられます。