| ページ一覧 | ブログ | twitter |  書式 | 書式(表) |

MyMemoWiki

「イベントディスパッチスレッド」の版間の差分

提供: MyMemoWiki
ナビゲーションに移動 検索に移動
1行目: 1行目:
==イベントディスパッチスレッド==
+
==[[イベントディスパッチスレッド]]==
[[Java]] | [[Swing]] | {{category 並行処理}}
+
[[Java]] | [[Swing]] | [[Category:並行処理]]
 
http://java.sun.com/docs/books/tutorial/uiswing/concurrency/dispatch.html
 
http://java.sun.com/docs/books/tutorial/uiswing/concurrency/dispatch.html
 
==GUIスレッド==
 
==GUIスレッド==
7行目: 7行目:
 
「特に意識的に完全にシングルスレッドのプログラムを書かないかぎり、普通のGUIアプリケーションでは、アプリケーションのスレッドとGUIのイベントスレッド、少なくともこの二つのスレッドが動きます。」
 
「特に意識的に完全にシングルスレッドのプログラムを書かないかぎり、普通のGUIアプリケーションでは、アプリケーションのスレッドとGUIのイベントスレッド、少なくともこの二つのスレッドが動きます。」
  
「昔はGUIのアプリケーションそのものがシングルスレッドで、GUIのイベントはアプリケーションのメインスレッドの中の"メインイベントループ(main event loop)” と呼ばれるループの中で処理されました。今日のGUIフレームワークはほんの少しだけ違って、イベントディスパッチスレッド(event dispatch thread,EDT)と呼ばれる、GUIイベントを処理する専用のスレッドを作ります。」
+
「昔はGUIのアプリケーションそのものがシングルスレッドで、GUIのイベントはアプリケーションのメインスレッドの中の"メインイベントループ(main event loop)” と呼ばれるループの中で処理されました。今日のGUIフレームワークはほんの少しだけ違って、[[イベントディスパッチスレッド]](event dispatch thread,EDT)と呼ばれる、GUIイベントを処理する専用のスレッドを作ります。」
  
[[http://www.amazon.co.jp/gp/product/4797337206?ie=UTF8&tag=typea09-22&linkCode=as2&camp=247&creative=7399&creativeASIN=4797337206 Java並行処理プログラミング ―その「基盤」と「最新API」を究める―]] |
+
[http://www.amazon.co.jp/gp/product/4797337206?ie=UTF8&tag=typea09-22&linkCode=as2&camp=247&creative=7399&creativeASIN=4797337206 Java並行処理プログラミング ―その「基盤」と「最新API」を究める―]
 
{{amazon|4797337206}}
 
{{amazon|4797337206}}
  
  
===Swing のイベントハンドリング===
+
===[[Swing]] のイベントハンドリング===
*Swing のイベントハンドリングコードは、イベントディスパッチスレッドと呼ばれる特別なスレッド上で実行されます。
+
*Swing のイベントハンドリングコードは、[[イベントディスパッチスレッド]]と呼ばれる特別なスレッド上で実行されます。
*ほとんどのコードは、Swingのメソッドを同様にこのスレッドで、呼び出します。
+
*ほとんどのコードは、[[Swing]]のメソッドを同様にこのスレッドで、呼び出します。
*これは、大抵のSwingオブジェクトのメソッドが、スレッドセーフでないため、必要です。
+
*これは、大抵の[[Swing]]オブジェクトのメソッドが、スレッドセーフでないため、必要です。
  
 
===スレッドセーフでないメソッドの呼び出し===
 
===スレッドセーフでないメソッドの呼び出し===
*いくつかのSwingコンポーネントメソッドはスレッドセーフとAPI仕様に記されています。
+
*いくつかの[[Swing]]コンポーネントメソッドはスレッドセーフとAPI仕様に記されています。
 
*これらは、どんなスレッドからでも安全に呼び出せます。
 
*これらは、どんなスレッドからでも安全に呼び出せます。
*その他のSwingコンポーネントメソッドは、イベントディスパッチスレッドから呼び出す必要があります。
+
*その他のSwingコンポーネントメソッドは、[[イベントディスパッチスレッド]]から呼び出す必要があります。
 
<blockquote>プログラムが、このルールを無視すると、ほとんどの場合きちんと機能するのに、予測や再現性のないエラーが発生しやすくなります。</blockquote>
 
<blockquote>プログラムが、このルールを無視すると、ほとんどの場合きちんと機能するのに、予測や再現性のないエラーが発生しやすくなります。</blockquote>
  
*Java Swing 非同期処理の結果をGUIに表示する
+
*[[Java Swing 非同期処理の結果をGUIに表示する]]
===コードがイベントディスパッチスレッド上で実行されているか===
+
===コードが[[イベントディスパッチスレッド]]上で実行されているか===
*短いタスクとして、コードがイベントディスパッチスレッド上で実行されているかを考慮することは実用的です。
+
*短いタスクとして、コードが[[イベントディスパッチスレッド]]上で実行されているかを考慮することは実用的です。
 
*ほとんどのタスクは、例えば、ActionListener.actionPerformedのような、イベントハンドリングメソッドとして呼び出されます。
 
*ほとんどのタスクは、例えば、ActionListener.actionPerformedのような、イベントハンドリングメソッドとして呼び出されます。
 
*別のタスクは、invokeLater や invokeAndWait を使ってアプリケーションによりスケジュールされます。
 
*別のタスクは、invokeLater や invokeAndWait を使ってアプリケーションによりスケジュールされます。
*コードがイベントディスパッチ上で動いているか確認するには、javax.swing.SwingUtilities.isEventDispatchThreadを呼び出します。
+
*コードがイベントディスパッチ上で動いているか確認するには、javax.swing.[[Swing]]Utilities.isEventDispatchThreadを呼び出します。
  
<blockquote>コントロール不能のイベントを中止したり、ユーザーインターフェースが無反応にならない為に、イベントディスパッチスレッド上のタスクは、すばやく完了しなければなりません。</blockquote>
+
<blockquote>コントロール不能のイベントを中止したり、ユーザーインターフェースが無反応にならない為に、[[イベントディスパッチスレッド]]上のタスクは、すばやく完了しなければなりません。</blockquote>
  
 
===例===
 
===例===
37行目: 37行目:
 
  import java.awt.Dimension;
 
  import java.awt.Dimension;
 
   
 
   
  import javax.swing.JFrame;
+
  import javax.swing.[[JFrame]];
 
  import javax.swing.JLabel;
 
  import javax.swing.JLabel;
  import javax.swing.SwingUtilities;
+
  import javax.swing.[[Swing]]Utilities;
 
   
 
   
 
   
 
   
45行目: 45行目:
 
   * @see http://java.sun.com/docs/books/tutorial/uiswing/components/frame.html
 
   * @see http://java.sun.com/docs/books/tutorial/uiswing/components/frame.html
 
   */
 
   */
  public class JFrameTest {
+
  public class [[JFrame]]Test {
   privat eJFrame frame;
+
   privat e[[JFrame]] frame;
 
   public static void main(String[] args) {
 
   public static void main(String[] args) {
     SwingUtilities.invokeLater(
+
     [[Swing]]Utilities.invokeLater(
         new Runnable(){
+
         new [[R]]unnable(){
 
           public void run() {
 
           public void run() {
             JFrameTest jft = new JFrameTest();
+
             [[JFrame]]Test jft = new [[JFrame]]Test();
 
             jft.createUI();
 
             jft.createUI();
 
           }
 
           }
59行目: 59行目:
 
   private void createUI() {
 
   private void createUI() {
 
     // Windowの生成
 
     // Windowの生成
     frame = new JFrame("FrameTest");
+
     frame = new [[JFrame]]("FrameTest");
 
     // Windowクローズ時にどうするか
 
     // Windowクローズ時にどうするか
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+
     frame.setDefaultCloseOperation([[JFrame]].EXIT_ON_CLOSE);
 
     // ダミーコンポーネント
 
     // ダミーコンポーネント
 
     JLabel lbl = new JLabel("");
 
     JLabel lbl = new JLabel("");
 
     lbl.setPreferredSize(new Dimension(200,100));
 
     lbl.setPreferredSize(new Dimension(200,100));
 
     // フレームにコンポーネントを乗せる
 
     // フレームにコンポーネントを乗せる
     frame.getContentPane().add(lbl, BorderLayout.CENTER);
+
     frame.getContentPane().add(lbl, BorderLayout.CENTE[[R]]);
 
     // サイズ調節
 
     // サイズ調節
 
     frame.pack();
 
     frame.pack();
72行目: 72行目:
 
     frame.setVisible(true);
 
     frame.setVisible(true);
 
      
 
      
     // debug イベントディスパッチスレッドか?
+
     // debug [[イベントディスパッチスレッド]]か?
     System.out.println("EventDispatchThread ? " + SwingUtilities.isEventDispatchThread());
+
     System.out.println("EventDispatchThread ? " + [[Swing]]Utilities.isEventDispatchThread());
 
   }
 
   }
 
  }
 
  }

2020年2月16日 (日) 04:19時点における版

イベントディスパッチスレッド

Java | Swing | http://java.sun.com/docs/books/tutorial/uiswing/concurrency/dispatch.html

GUIスレッド

「ほとんどすべてのGUIツールキットはシングルスレッドのサブシステム(single-threded subsystem)として実装されています。すなわちすべてのGUI活動が一つのスレッドに拘束されています。」

「特に意識的に完全にシングルスレッドのプログラムを書かないかぎり、普通のGUIアプリケーションでは、アプリケーションのスレッドとGUIのイベントスレッド、少なくともこの二つのスレッドが動きます。」

「昔はGUIのアプリケーションそのものがシングルスレッドで、GUIのイベントはアプリケーションのメインスレッドの中の"メインイベントループ(main event loop)” と呼ばれるループの中で処理されました。今日のGUIフレームワークはほんの少しだけ違って、イベントディスパッチスレッド(event dispatch thread,EDT)と呼ばれる、GUIイベントを処理する専用のスレッドを作ります。」

Java並行処理プログラミング ―その「基盤」と「最新API」を究める―


Swing のイベントハンドリング

  • Swing のイベントハンドリングコードは、イベントディスパッチスレッドと呼ばれる特別なスレッド上で実行されます。
  • ほとんどのコードは、Swingのメソッドを同様にこのスレッドで、呼び出します。
  • これは、大抵のSwingオブジェクトのメソッドが、スレッドセーフでないため、必要です。

スレッドセーフでないメソッドの呼び出し

  • いくつかのSwingコンポーネントメソッドはスレッドセーフとAPI仕様に記されています。
  • これらは、どんなスレッドからでも安全に呼び出せます。
  • その他のSwingコンポーネントメソッドは、イベントディスパッチスレッドから呼び出す必要があります。

<blockquote>プログラムが、このルールを無視すると、ほとんどの場合きちんと機能するのに、予測や再現性のないエラーが発生しやすくなります。</blockquote>

コードがイベントディスパッチスレッド上で実行されているか

  • 短いタスクとして、コードがイベントディスパッチスレッド上で実行されているかを考慮することは実用的です。
  • ほとんどのタスクは、例えば、ActionListener.actionPerformedのような、イベントハンドリングメソッドとして呼び出されます。
  • 別のタスクは、invokeLater や invokeAndWait を使ってアプリケーションによりスケジュールされます。
  • コードがイベントディスパッチ上で動いているか確認するには、javax.swing.SwingUtilities.isEventDispatchThreadを呼び出します。

<blockquote>コントロール不能のイベントを中止したり、ユーザーインターフェースが無反応にならない為に、イベントディスパッチスレッド上のタスクは、すばやく完了しなければなりません。</blockquote>

import java.awt.BorderLayout;
import java.awt.Dimension;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;


/**
 * @see http://java.sun.com/docs/books/tutorial/uiswing/components/frame.html
 */
public class JFrameTest {
  privat eJFrame frame;
  public static void main(String[] args) {
    SwingUtilities.invokeLater(
        new Runnable(){
          public void run() {
            JFrameTest jft = new JFrameTest();
            jft.createUI();
          }
        }
    );
  }
  private void createUI() {
    // Windowの生成
    frame = new JFrame("FrameTest");
    // Windowクローズ時にどうするか
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    // ダミーコンポーネント
    JLabel lbl = new JLabel("");
    lbl.setPreferredSize(new Dimension(200,100));
    // フレームにコンポーネントを乗せる
    frame.getContentPane().add(lbl, BorderLayout.CENTER);
    // サイズ調節
    frame.pack();
    // 表示
    frame.setVisible(true);
    
    // debug イベントディスパッチスレッドか?
    System.out.println("EventDispatchThread ? " + SwingUtilities.isEventDispatchThread());
  }
}