看到别人写的代码:EventQueue.invokeLater(new Runnable()
{
    public void run()
    {
       ....
    }
});
看起来像是启动一个线程,并在线程中做一些事情,为什么放在EventQueue.invokeLater中呢?(为什么不直接创建一个Thread对象)这是什么意思呢?这种写法主要用于什么场合呢?

解决方案 »

  1.   

    awt是单线程模式的,所有awt的组件只能在事件处理线程中访问,从而保证组件状态的可确定性。 
      

  2.   

    这样是为了防止出现类似于 一个 任务需要大量时间处理时,你的界面不会死掉。你可以去查下 EventQueue 的工作原理,大概是下面的:   简单来讲,在EventQueue中有一个dispatchThread,这是个线程类,负责事件的分发,当Queue中有事件的时候,他会摘取前面的事件并分发给相应的对象进行处理,等处理完之后再获取下一个,当Queue中没有事件的时候,线程等待。    当有事件触发时,系统会调用EventQueue的push方法将AWTEvent添加到EventQueue的最后,同时唤醒dispatchThread。     为什么界面会死掉    所以能看到,Swing的事件分发实际上是同步的,并且都是在dispatchThread这个线程中处理的,也就是说是个事件一个事件处理的,如果有某一个事件处理的时间非常长的时侯,其他事件就会被堵塞在那里,从现象上看得话,就是界面会死掉,如果界面被其他窗口覆盖之后再回到前面的时侯,会变成一片灰色,这是因为PaintEvent被堵塞而不能被分发出去的缘故。
      

  3.   

    run里的代码会在将来的某个时间被调用
      

  4.   

    也可以用thread对象,thread也实现了Runnable接口
      

  5.   

    lz主的问题其实很简单
    在java中并不像别的语言那样能直接传入一个代码块,而是传入一个对象
    其中:
    EventQueue.invokeLater(new Runnable()
    {
        public void run()
        {
           ....
        }
    });
    的 new Runnable(){run()}只是一种创建对象的简便方式,这样写避免了先创建一个继承Runable接口的
    类,然后再创建对象,所以比较简便,在多线程中经常用到。
    具体的请看一下面向对象中对面向接口编程的介绍
      

  6.   

    ls 的理解错了,你说的这种创建对象的简便写法我知道。我现在想问的只是
    EventQueue.invokeLater(...)这种写法。这种写法我以前没用过,
    我以前用的都是直接创建一个线程对象来做,故请教两者的区别。
      

  7.   

    EventQueue.invokeLater相当于,定义了一个任务,这个任务在将来的某个时刻被awt线程调用执行。
    就好比,放学了,老师给你布置个任务。你回家做。
      

  8.   

    new Runnable() {} 创建一个“可以被执行”的对象,但这个对象具体什么时候开始执行由EventQueue来决定。通常你所写的new Thread().start()是创建了这个可执行对象,并且开始执行
      

  9.   

    因为 awt, 或者 swing 为了确保所有的组件是同步的,所以他被设计为单线程的,同一时刻,只有一个线程(事件分发线程,EDT)在操作 组件。所以,要想能正确运行,用户也必须在事件分发线程中操作组件,EventQueue.invokeLater(Runnable),提供了这个方法,让用户的操作在事件分发线程中完成。
      

  10.   

    其实用Thread类也是可以的,只要你不启动这个Thread,效果和Runnable一样
    你可以试一下EventQueue.invokeLater(new Thread() {
        public void run() {
            ....
        }
    });
      

  11.   

    EventQueue定义了一个invokeLater(Runnable instance)方法
    调用的时候EventQueue.invokeLater(new Runnable(){public void run(){};})
    其中的参数并不是实现创建好的,而是在调用的时候才创建;
    也可以EventQueue.invokeLater(runnableInstance);
    前提是runnableInstance实现了Runnable接口