当前位置: 首页 > 面试题库 >

摆动线程安全编程

令狐俊风
2023-03-14
问题内容
public static void main(String args[]) {
    /* Set the Nimbus look and feel */
    //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
    /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
     * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
     */
    try {
        for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
            if ("Nimbus".equals(info.getName())) {
                javax.swing.UIManager.setLookAndFeel(info.getClassName());
                break;
            }
        }
    } catch (ClassNotFoundException ex) {
        java.util.logging.Logger.getLogger(MyDialog.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (InstantiationException ex) {
        java.util.logging.Logger.getLogger(MyDialog.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (IllegalAccessException ex) {
        java.util.logging.Logger.getLogger(MyDialog.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (javax.swing.UnsupportedLookAndFeelException ex) {
        java.util.logging.Logger.getLogger(MyDialog.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    }
    //</editor-fold>

    /* Create and display the dialog */
    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            MyDialog dialog = new MyDialog(new javax.swing.JFrame(), true);
            dialog.addWindowListener(new java.awt.event.WindowAdapter() {
                @Override
                public void windowClosing(java.awt.event.WindowEvent e) {
                    System.exit(0);
                }
            });
            dialog.setVisible(true);
        }
    });
}

MyDialog类只有很少的组合和文本字段,并且正在用DB值填充组合。在选择一个组合值时,我从数据库获取了另一个值以填充下一个组合。

上面的程序以相同的方式运行,而不使用invokeLater线程。什么时候invokeLater在Swing编程中变得有用。我已经读过一些,但似乎都是理论上的。invokeLater对应用程序有什么区别?仅在main方法内部使用它就足够了还是应该在操作侦听器中使用它?

SwingUtilities.invokeLater和java.awt.EventQueue.invokeLater-相同吗?


问题答案:

没有什么理论上的。这很实用。该SwingUtilities.invokeLater()方法可确保中的代码Runnable将在上运行Event Dispatch Thread (EDT)。这很重要,因为Swing并非线程安全的,因此与GUI(Swing等)相关的所有操作都需要在上运行EDT。这EDT是一个“发生时便会发生”的线程,该线程不保证执行顺序。如果GUI代码是在后台线程(例如,在一个SwingWorker实例中)内执行的,则可能引发错误。我很难学到这一点:在我的学习生涯中,在后台线程中执行GUI更改代码会导致RuntimeException我无法弄清的随机不一致的错误。这是一次很好的学习经历(SwingWorker有一种doInBackground()后台任务的方法和一个done()``EDT任务方法)。

与您不想在后台线程上执行GUI代码的方式相同,您也不想在上执行大型操作(数据库查询等)EDT。这是因为EDT调度所有GUI事件,因此上的所有内容都EDT应该简短而优美。您可以JProgressBar通过不确定的集合轻松地看到这一点。

该SSCCE应该很好地说明它。请注意JProgressBaras 的运动method(),一次在后台线程上,一次在EDT线程上。

import javax.swing.JFrame;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;

/**
 *
 * @author Ryan
 */
public class Test {

    public static void main(String args[]) {
        JFrame frame = new JFrame();
        JProgressBar jpb = new JProgressBar();
        jpb.setIndeterminate(true);
        frame.add(jpb);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        new Task().execute();
    }

    public static void method() { // This is a method that does a time-consuming task.
        for(int i = 1; i <= 5; i++) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(i);
        }
    }

    static class Task extends SwingWorker<Void, Void> {

        @Override
        protected Void doInBackground() throws Exception {
            /* Executing method on background thread.
             * The loading bar should keep moving because, although method() is time consuming, we are on a background thread.
            */ 
            method();
            return null;
        }

        @Override
        protected void done() {
            /* Executing method on Event Dispatch Thread.
             * The loading bar should stop because method() is time consuming and everything on the Event Dispatch Thread
             * (like the motion of the progress bar) is waiting for it to finish.
            */

            // 
            method();
        }
    }
}

希望这可以帮助。



 类似资料:
  • 我有一个带有一些线程的简单应用程序,我需要从一些线程更新SWING GUI(我正在使用Netbean)。 这是我需要更新的主要表单: 现在我有一些线程: 在其他班级,我有: 代码的每个部分都位于不同的文件(类)中。我如何在这里实现 Swing 工作人员,以便能够在我的主 GUI 窗体上显示文本?

  • 问题内容: HttpUrlConnection线程安全吗?即,如果我有一个连接到服务器的HttpConnection实例,并且该实例被不同的线程使用(例如,尝试同时发送POST),HttpUrlConnection将如何处理这种情况?a)他们将串行发送POST,还是b)第一个线程发送POST,获取响应,然后第二个线程发送POST?如果它们以串行方式发送POST,则意味着到同一tcp连接的多个活动P

  • 假设我有一个Executors静态工厂方法的ExecutorService实例。 如果我从某个线程提交了一个调用,其中RetVal不是线程安全的本地实例化对象,那么当我从同一个线程获得()它时,我需要担心retvals的完整性吗?人们说局部变量是线程安全的,但我不确定当您返回一个本地实例化的对象并从其他线程接收它时,它是否适用。 下面是我的定制实现,我只是为了测试。您可以忽略EType枚举。

  • 在PHP初期,是作为单进程的CGI来运行的,所以并没有考虑线程安全问题。 我们可以随意的在全局作用域中设置变量并在程序中对他进行修改、访问,内核申请的资源如果没有正确的释放, 也会在CGI进程结束后自动地被清理干净。 后来,php被作为apache多进程模式下的一个模块运行,但是这仍然把php局限在一个进程里, 我们设置的全局变量,只要在每个请求之前将其正确的初始化,并在每个请求之后正确的清理干净

  • 这是一套 Python 系列教程,学习本套教程不需要你有任何编程背景。教程由最简单的hello world到信息安全应用实例。

  • 当仅仅声明式安全是不足以表达应用的安全模型时,编程式安全被用于意识到安全的应用。 编程式安全包括以下 HttpServletRequest 接口的方法: authenticate login logout getRemoteUser isUserInRole getUserPrincipal login 方法允许应用执行用户名和密码收集(作为一种 Form-Based Login 的替代)。 au