SwingUtilities.invokeLater(new Runnable() {}について

このQ&Aのポイント
  • SwingUtilities.invokeLater(new Runnable() {}は何をするのか説明してください
  • APIを見ても理解できないSwingUtilities.invokeLater(new Runnable() {}について教えてください
  • SwingUtilities.invokeLater(new Runnable() {}の効果や使い方について教えてください
回答を見る
  • ベストアンサー

SwingUtilities.invokeLater(new Runn

SwingUtilities.invokeLater(new Runnable() {}について 以前質問でgooで教えて頂いた際、以下のようなコードがありました。 どのような効果があるのか教えてください。 APIを見ても理解できませんでした。 また、APIを理解するコツのようなものはあるでしょうか。 ご存知の方がおられましたら教えてください。 ・試してみたこと  重いプログラムを起動させ、実行速度を比べた。------ほとんど同じでした。   public static void main(String a[]) { SwingUtilities.invokeLater(new Runnable() { public void run() { new test(); } }); }

  • Java
  • 回答数1
  • ありがとう数1

質問者が選んだベストアンサー

  • ベストアンサー
  • PecoPlus
  • ベストアンサー率76% (144/188)
回答No.1

 こんにちは。  これについては、知らなければ、訳がわからないのも無理がないと思います。  Swing はシングルスレッド設計になっています。  複数のスレッドに同時にアクセスされることを考慮されていません。  よって、何か長い処理を別スレッドで実行したとしても、Swing コンポーネントにアクセスするときだけは、SwingUtilities#invokeLater() メソッドなどを使い、イベントディスパッチスレッドに、アクセス部分の処理を委譲します。  まあ、ここまでは、いいのですが、ご質問の件です。  昔は、普通に public static void main(String[] args) {   JFrame frame = new JFrame();   ・・・   ・・・   frame.setVisible(true); }  こう書いていました。  しかし、ある時、誰か偉い人が、「これって、やばいんじゃない?」と気がついてしまったわけです。  元々、JFrame の構築の段階で、メインスレッドがアクセスしてしまっていますが、イベントディスパッチスレッドが走り始めるのは、JFrame#setVisble() メソッドの時なので、これは、これで、大丈夫だろうと思われていました。  しかし、JFrame#setVisible() メソッド内部で、メインスレッドが残っている間に、いくつかのイベントが発生してしまい、わずかながら Swing コンポーネントに複数スレッドが同時アクセスする時間があると言うことです。  まあ、ほとんどの場合は、問題ないのですが、「問題が発生するかもしれないし、しないかもしれない」ということが問題なのです。 「じゃあ、最初から、イベントディスパッチスレッドにお任せしよう」ということになって、こんな呪文めいた儀式が行われるようになったわけです。

参考URL:
http://d.hatena.ne.jp/torutk/20060928#p2
hatokamome
質問者

お礼

ありがとうございます。 すごく奥深いのですね。 プログラムが楽しくなってきました。

関連するQ&A

  • SwingUtilities.invokeLater(new Runnable()はなんですか?

    Javaのmain()にあるこれはなに? SwingUtilities.invokeLater(new Runnable(){ これはなんですか? IDEによって自動的に追加されたみたいですが、消すとなにか問題がありますか?

  • SwingでSwingUtilities.invokeLater()の利用

    はじめまして。Javaビギナーです。 今Swingを利用したチャットアプリを作成しようと色々調べているところなのですが、よくmain()メソッド内にて public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { // 初期処理 } }); } というのを見かけます。 これは、Swingでアプリを実行する場合に上記のように作成することが一般的なのでしょうか? それとも、マルチスレッドを利用する必要のない場合などは上記のようなコーディングは行われないのでしょうか? 後々の機能拡張などを考えれば、上記のようにコーディングした方が良いのだと思いますが、一般的な利用方法を教えていただければと思います。宜しくお願いします。

  • Java言語のインタフェースについて

    Java言語を学習している者です。 インターフェースについて理解できずに困っております。 ここでは、Runnableインターフェースを例にとります。 (1)正しいコード public class ThreadTest implements Runnable { public static void main (String args[]) { ThreadTest ins = new ThreadTest(); Thread th = new Thread(ins); th.start(); for(int i = 0; i < 10; i++) { System.out.println("main : " + i); } } public void run() { for(int i = 0; i < 10; i++) { System.out.println("run : " + i); } } } (1)のコードは正常に動きます。 (2)間違ったコード (implements Runnableを記述しなかった場合) public class ThreadTest{ public static void main (String args[]) { ThreadTest ins = new ThreadTest(); Thread th = new Thread(ins); th.start(); for(int i = 0; i < 10; i++) { System.out.println("main : " + i); } } public void run() { for(int i = 0; i < 10; i++) { System.out.println("run : " + i); } } } (2)のコードでは、 Thread th = new Thread(ins); で、 コンストラクタ―Thread(ThreadTest)は未定義です。 とエラーが出てしまいます。 確かに未定義なのですが、(1)でも定義していないように思えます。 Runnableインターフェースの働きのお陰だと言うことはわかるのですが、どういった働きによるものなのかがわかりません。 インターフェースのについて、 ・インターフェースのフィールドは必ず定数。 ・インターフェースのメソッドは必ず抽象メソッド。 ・インターフェースはインスタンスを作ることが出来ない。 ・抽象メソッドは必ず実装しなければならない。 は理解しているつもりです。 今回の質問をするに当たって、 RunnableのAPI http://java.sun.com/javase/ja/6/docs/ja/api/java/lang/Runnable.html を見たのですが、それでも理由が分からないので質問致します。 もし宜しかったら、APIの見方についてもコメントして頂けるとありがたいです。 宜しくお願いします。

    • ベストアンサー
    • Java
  • コンパイルエラー(Threadオブジェクト化)

    Runnableを継承したNormalClassをThreadとしてオブジェクト化しようとしているのですが、コンパイルエラーが出現して困っています。どうすればいいでしょうか? 下記エラー参照 Main.java:1: NormalClass は abstract でなく、java.lang.Runnable 内の abstract メソッド run() をオーバーライドしません。 下記ソース class NormalClass implements Runnable{ } class Main extends Thread{ public static void main(String args[]){ test = new Thread(new NormalClass()); } }

    • ベストアンサー
    • Java
  • Runnableのインスタンス化について

    下記のコードについてです。 Runnableがインスタンス化されていますが、 どうしてそれが可能なのかが分かりません。 分からない点は 1.Runnableはインタフェースであるから、本来、直接インスタンス化は不可能であるはず。 2.しかし、Runnableはクラスライブラリjava.langパッケージに含まれている。 だからインスタンス化は可能なのかもしれない。 3.あるいは、下記のコードではメソッド内の無名クラスであるから、「new Runnable(){」の 部分でスーパークラスとしてのRunnableを継承したサブクラスを生成しているのかもしれない。 アドバイスをよろしくお願い致します。 public class Main{ public static void main(String[]args){ Runnable task = new Runnable(){ public void run(){ System.out.println("run"); } }; Thread thread = new Thread(task){ public synchronized void start(){ System.out.println("start"); } }; thread.start(); } }

    • ベストアンサー
    • Java
  • 実行の順番を教えてください。

    現在JAVAの学習をおこなっていて、参考書で勉強しています。 しかし、以下の3つのソースコードはどの順番で実行されているか理解できておりません。 すみませんが、実行の順番を教えて頂けないでしょうか。 実行の順に数字を振ったりしていただけますと特に嬉しいです。 お願いします。 ※サンプル1 class testA{ testB b; testA(){ b=new testB(this); } } class testB{ testA a; testB(testA a){ this.a=a; } } class testAll{ public static void main(String args[]){ new testAll().banana(); //ソースコード } void banana(){ testA test = new testA(); } } ※サンプル2 public class A{ public static void apple(Integer i){ int ta =i.intValue(); ta+=3 ; i=new Integer(ta); } public static void main(String args[]){ Integer i = new Integer (0); apple(i); System.out.println(i.intValue()); } } ※サンプル3 public class Test{ public static void main (String args[]){ class orange{ public int i =9; } Object o=(Object)new orange(); orange orange = (orange)o; System.out.println("i="+orange.i); } }

    • ベストアンサー
    • Java
  • java8でテキストのレンダリングが不正になる

    先日java8をインストールしたのですが、JMenu/JButton/JLabelなどの文字やボーダーが一部欠けたように表示されるようになりました(画像を添付しました)。 java7では再現しないことから色々探してみると下記サイトで同件と思われるレポートを見つけました。 http://stackoverflow.com/questions/22737535/swing-rendering-appears-broken-in-jdk-1-8-correct-in-jdk-1-7 しかし「NVIDIAのカードの設定を変えたら動くようになった」というコメント以外に対応策らしきものがなく、それを自分も試してみたものの解決せずでした。 もしjava8の問題ならしばらくはjava7を使い続けるしかないとは思うのですが、同件と思われる問題が上記サイト以外に見つけられなかったことからjava8問題だというのは早計かとも思い、諦めてしまう前に「同じ現象になったよ」「こうしたら動いた」「コードに問題がある」などの情報がないかと思い質問を上げさせていただきました。コメントいただけたらありがたいです。 再現コード: package jp.po.test1; import java.awt.Font; import javax.swing.*; public class Test1 extends JFrame { public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { new Test1().setVisible(true); } }); } Test1() { super("title"); JLabel label = new JLabel("BOO FOO WOO"); label.setFont(new Font(Font.DIALOG, Font.PLAIN, 30)); getContentPane().add(label); setDefaultCloseOperation(EXIT_ON_CLOSE); pack(); } }

    • ベストアンサー
    • Java
  • new Runnable() runメソッド

    以下ソースコードの@Override注釈を入れるとエラーになります。 Runnableインターフェースではrumメソッドをオーバーライドする必要があると思うのですが、 @Override注釈を入れるとエラーになります。 @Override注釈を入れないとエラーにならず実行できます。 環境はEclipseで、Androidのエミュレーターへ出力してテスト中です。 どなたか原因をご存じの方がおられましたら、アドバイスよろしくお願い致します。 public void startTimer(){ final Handler handler = new Handler(); TimerTask task = new TimerTask(){ @Override public void run() { handler.post(new Runnable(){ //@Override ←ここを記入するとエラーになる。 public void run() { board.doComp(); invalidate(); timer.cancel(); if (!board.isPlaying) return; if (board.isPass(board.you)){ board.addMessage("あなたは、パスです。"); showMsg("あなたは、パスです。"); startTimer(); } else { board.canMove = true; } } }); } }; timer = new Timer(); timer.schedule(task, 1000); }

    • ベストアンサー
    • Java
  • NoSuchMethodErrorが解決できません。

    実行時エラーNoSuchMethodErrorが出て困っています。 どこを修正すればいいのでしょうか? class A implements Runnable{ int x; int y; public void run(){ for(int i = 0;i < 100;i++){ x++; y++; System.out.println("x="+x+"y="+y); } } } class B{ public static void main(String args[]){ new Thread(new A()).start(); new Thread(new A()).start(); } }

    • ベストアンサー
    • Java
  • synchronizedを使用方法で混乱しています。

    JAVAを独学で勉強しております。synchronizedをインスタンスメソッドに使用したのですが、同期化できません。いくら考えてもわからなかったので、質問しました。ソースを記入します。 class Test extends Thread{ public void run(){ ss(); } public synchronized void ss(){ for(int x=1;x<=10;x++){ System.out.println(Thread.currentThread().getName()); } } public static void main(String[] args){ Test t1 =new Test(); Test t2 =new Test(); Test t3 =new Test(); t1.start(); t2.start(); t3.start(); } } 実行すると、同期化されてなく、ランダムに表示されます。違うオブジェクトで参照しているから、ロックかけても意味がないのかなーとも思っていますが、 Threadの拡張じゃなく、Runnableの実装に書き換えると同期化されます。なぜでしょう?自分なりに精一杯考えましたがわかりません。分かる方、説明お願いできますでしょうか?

    • ベストアンサー
    • Java

専門家に質問してみよう