简体   繁体   English

在actionPerformed和Event Dispatch Thread(EDT)问题中创建新线程

[英]create new thread inside actionPerformed and Event Dispatch Thread (EDT) issue

As stated from Sun that actionPerformed() from ActionListener is executed in EDT automatically so I've decided to create new thread inside actionPerformed() method and the problem is this thread is not running inside EDT. 正如Sun所说,来自ActionListener的actionPerformed()是在EDT中自动执行的,因此我决定在actionPerformed()方法中创建新线程,问题是该线程不在EDT中运行。 Can someone explain this? 有人可以解释吗? Thanks 谢谢

If you create a new thread from EDT that thread is different than the EDT. 如果从EDT创建新线程,则该线程与EDT不同。 Isn't that clear? 不清楚吗?
You are supposed to update controls via the EDT. 您应该通过EDT更新控件。
You can create your own background threads for heavy tasks but the update of the controls should be only via the EDT. 您可以为繁重的任务创建自己的后台线程,但是控件的更新只能通过EDT进行。 There are constructs for you to use to facilitate your code eg pass a Runnable to be called by EDT via SwingUtilities invoke Runnable . 有结构供你使用,以方便您的代码,例如通过一个Runnable于由EDT通过所谓的SwingUtilities调用Runnable接口 You should study about Concurrency in Swing 您应该学习Swing中的并发性

1) AWT or Swing GUI invoked and created EDT, this event is done by (maybe there are another) methods pack() and setVisible(true) 1)调用和创建EDT的AWT或Swing GUI,此事件由(可能还有其他)方法pack()和setVisible(true)完成

2) if all events waiting in EDT are done and EDT is empty then if (EventQueue.isDispatchThread()) { returns false, but EDT thread is there until current JVM instance exist 2)如果在EDT中等待的所有事件都已完成并且EDT为空,则如果(EventQueue.isDispatchThread()){返回false,但是EDT线程存在,直到当前的JVM实例存在

3) as mentioned for invoke EDT queue you can use invokeLater or invokeAndWait, notice invokeAndWait you can use only if isDispatchThread returns false, otherwise returns exceptions 3)如提到的调用EDT队列,您可以使用invokeLater或invokeAndWait,请注意invokeAndWait仅在isDispatchThread返回false时可以使用,否则返回异常

4) by calling Thread.sleep(int) from Swing Listener or its method can freeze and lock EDT, causing lost some event from event queue, 4)通过从Swing侦听器调用Thread.sleep(int)或其方法可以冻结并锁定EDT,从而导致事件队列中的某些事件丢失,

two codes example for testing isDispatchThread() and how to alive EDT from Java Objects 两个代码示例,用于测试isDispatchThread()以及如何从Java Objects激活EDT

import java.awt.EventQueue;
import java.lang.reflect.InvocationTargetException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;

public class IsThereEDT {

    private ScheduledExecutorService scheduler;
    private AccurateScheduledRunnable periodic;
    private ScheduledFuture<?> periodicMonitor;
    private int taskPeriod = 30;
    private SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
    private Date dateRun;
    private JFrame frame1 = new JFrame("Frame 1");

    public IsThereEDT() {
        scheduler = Executors.newSingleThreadScheduledExecutor();
        periodic = new AccurateScheduledRunnable() {

            private final int ALLOWED_TARDINESS = 200;
            private int countRun = 0;
            private int countCalled = 0;
            private int maxCalled = 10;

            @Override
            public void run() {
                countCalled++;
                if (countCalled < maxCalled) {
                    if (countCalled % 3 == 0) {
                        /*if (EventQueue.isDispatchThread()) {
                            SwingUtilities.invokeLater(new Runnable() {

                                @Override
                                public void run() {
                                    //some stuff
                                }
                            });
                        } else {
                            try {
                                SwingUtilities.invokeAndWait(new Runnable() {

                                    @Override
                                    public void run() {
                                        //some stuff
                                    }
                                });
                            } catch (InterruptedException ex) {
                                Logger.getLogger(IsThereEDT.class.getName()).log(Level.SEVERE, null, ex);
                            } catch (InvocationTargetException ex) {
                                Logger.getLogger(IsThereEDT.class.getName()).log(Level.SEVERE, null, ex);
                            }
                        }*/
                        SwingUtilities.invokeLater(new Runnable() {

                            @Override
                            public void run() {
                                System.out.println("Push a new event to EDT");
                                frame1.repaint();
                                isThereReallyEDT();
                            }
                        });
                    } else {
                        if (this.getExecutionTime() < ALLOWED_TARDINESS) {
                            countRun++;
                            isThereReallyEDT(); // non on EDT
                        }
                    }
                } else {
                    System.out.println("Terminating this madness");
                    System.exit(0);
                }
            }
        };
        periodicMonitor = scheduler.scheduleAtFixedRate(periodic, 0, taskPeriod, TimeUnit.SECONDS);
        periodic.setThreadMonitor(periodicMonitor);
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                isThereReallyEDT();
                frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame1.getContentPane().add(new JLabel("Hello in frame 1"));
                frame1.pack();
                frame1.setLocation(100, 100);
                frame1.setVisible(true);
            }
        });
        try {
            Thread.sleep(500);
        } catch (InterruptedException ex) {
            Logger.getLogger(IsThereEDT.class.getName()).log(Level.SEVERE, null, ex);
        }
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                JFrame frame2 = new JFrame("Frame 2");
                frame2.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame2.getContentPane().add(new JLabel("Hello in frame 2"));
                frame2.pack();
                frame2.setLocation(200, 200);
                frame2.setVisible(true);
                isThereReallyEDT();
            }
        });
    }

    private void isThereReallyEDT() {
        dateRun = new java.util.Date();
        System.out.println("                         Time at : " + sdf.format(dateRun));
        if (EventQueue.isDispatchThread()) {
            System.out.println("EventQueue.isDispatchThread");
        } else {
            System.out.println("There isn't Live EventQueue.isDispatchThread, why any reason for that ");
        }
        if (SwingUtilities.isEventDispatchThread()) {
            System.out.println("SwingUtilities.isEventDispatchThread");
        } else {
            System.out.println("There isn't Live SwingUtilities.isEventDispatchThread, why any reason for that ");
        }
        System.out.println();
    }

    public static void main(String[] args) {
        IsThereEDT isdt = new IsThereEDT();
    }
}

abstract class AccurateScheduledRunnable implements Runnable {

    private ScheduledFuture<?> thisThreadsMonitor;

    public void setThreadMonitor(ScheduledFuture<?> monitor) {
        this.thisThreadsMonitor = monitor;
    }

    protected long getExecutionTime() {
        long delay = -1 * thisThreadsMonitor.getDelay(TimeUnit.MILLISECONDS);
        return delay;
    }
}

and simpler code 和更简单的代码

.

.

import java.awt.EventQueue;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;

public class IsThereEDT {

    private ScheduledExecutorService scheduler;
    private AccurateScheduledRunnable periodic;
    private ScheduledFuture<?> periodicMonitor;
    private int taskPeriod = 30;
    private SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
    private Date dateRun;
    private JFrame frame1 = new JFrame("Frame 1");

    public IsThereEDT() {
        scheduler = Executors.newSingleThreadScheduledExecutor();
        periodic = new AccurateScheduledRunnable() {

            private final int ALLOWED_TARDINESS = 200;
            private int countRun = 0;
            private int countCalled = 0;
            private int maxCalled = 10;

            @Override
            public void run() {
                countCalled++;
                if (countCalled < maxCalled) {
                    if (countCalled % 3 == 0) {
                        SwingUtilities.invokeLater(new Runnable() {

                            @Override
                            public void run() {
                                System.out.println("Push a new event to EDT");
                                frame1.repaint();
                                isThereReallyEDT();
                            }
                        });
                    } else {
                        if (this.getExecutionTime() < ALLOWED_TARDINESS) {
                            countRun++;
                            isThereReallyEDT(); // non on EDT
                        }
                    }
                } else {
                    System.out.println("Terminating this madness");
                    System.exit(0);
                }
            }
        };
        periodicMonitor = scheduler.scheduleAtFixedRate(periodic, 0, taskPeriod, TimeUnit.SECONDS);
        periodic.setThreadMonitor(periodicMonitor);
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                isThereReallyEDT();
                frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame1.getContentPane().add(new JLabel("Hello in frame 1"));
                frame1.pack();
                frame1.setLocation(100, 100);
                frame1.setVisible(true);
            }
        });
        try {
            Thread.sleep(500);
        } catch (InterruptedException ex) {
            Logger.getLogger(IsThereEDT.class.getName()).log(Level.SEVERE, null, ex);
        }
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                JFrame frame2 = new JFrame("Frame 2");
                frame2.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame2.getContentPane().add(new JLabel("Hello in frame 2"));
                frame2.pack();
                frame2.setLocation(200, 200);
                frame2.setVisible(true);
                isThereReallyEDT();
            }
        });
    }

    private void isThereReallyEDT() {
        dateRun = new java.util.Date();
        System.out.println("                         Time at : " + sdf.format(dateRun));
        if (EventQueue.isDispatchThread()) {
            System.out.println("EventQueue.isDispatchThread");
        } else {
            System.out.println("There isn't Live EventQueue.isDispatchThread, why any reason for that ");
        }
        if (SwingUtilities.isEventDispatchThread()) {
            System.out.println("SwingUtilities.isEventDispatchThread");
        } else {
            System.out.println("There isn't Live SwingUtilities.isEventDispatchThread, why any reason for that ");
        }
        System.out.println();
    }

    public static void main(String[] args) {
        IsThereEDT isdt = new IsThereEDT();
    }
}

abstract class AccurateScheduledRunnable implements Runnable {

    private ScheduledFuture<?> thisThreadsMonitor;

    public void setThreadMonitor(ScheduledFuture<?> monitor) {
        this.thisThreadsMonitor = monitor;
    }

    protected long getExecutionTime() {
        long delay = -1 * thisThreadsMonitor.getDelay(TimeUnit.MILLISECONDS);
        return delay;
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 actionPerformed(ActionEvent e)是否在与事件调度线程(EDT)不同的线程中运行? - Does actionPerformed(ActionEvent e) runs in a different thread than the Event Dispatch Thread (EDT)? 在swing中执行的action内创建新线程是否安全? - is it safe to create a new thread inside actionPerformed in swing? 使线程在EDT的非EDT(事件调度线程)线程上运行 - Make thread run on non EDT (event dispatch thread) thread from EDT Java:我应该在事件分发线程(EDT)中记录问题吗? - Java: Should I be logging issues in the event dispatch thread (EDT)? 如何检查 Swing 应用程序是否正确使用 EDT(事件分配线程) - How to check a Swing application for correct use of the EDT (Event DIspatch Thread) 如何捕获事件调度线程(EDT)异常? - How can i catch Event Dispatch Thread (EDT) exceptions? 是否应该由EDT(事件调度线程)执行代码之间的混淆? - Confusion between whether a code should be executed by EDT (Event Dispatch Thread) or not? 有没有办法设置两个或多个事件调度线程(EDT)? - Is there a way to set up two or more the event dispatch thread (EDT)? 在 EDT 线程中创建 JFrame 的实例是不好的做法吗? - Is it bad practice to create an instance of JFrame inside EDT thread? 如何检查EDT(事件调度线程)是否已完成在Java中调度事件 - How To Check Whether EDT (Event Dispatch Thread) Has finished with Dispatching Events In Java
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM