EventQueue.invokeLater(new Runnable()
{
public void run()
{
....
}
});
看起来像是启动一个线程,并在线程中做一些事情,为什么放在EventQueue.invokeLater中呢?
(为什么不直接创建一个Thread对象)
这是什么意思呢?
这种写法主要用于什么场合呢?
25 个解决方案
#1
awt是单线程模式的,所有awt的组件只能在事件处理线程中访问,从而保证组件状态的可确定性。
#2
对于这点我也不是明白
#3
这样是为了防止出现类似于 一个 任务需要大量时间处理时,你的界面不会死掉。
你可以去查下 EventQueue 的工作原理,大概是下面的:
简单来讲,在EventQueue中有一个dispatchThread,这是个线程类,负责事件的分发,当Queue中有事件的时候,他会摘取前面的事件并分发给相应的对象进行处理,等处理完之后再获取下一个,当Queue中没有事件的时候,线程等待。
当有事件触发时,系统会调用EventQueue的push方法将AWTEvent添加到EventQueue的最后,同时唤醒dispatchThread。
为什么界面会死掉
所以能看到,Swing的事件分发实际上是同步的,并且都是在dispatchThread这个线程中处理的,也就是说是个事件一个事件处理的,如果有某一个事件处理的时间非常长的时侯,其他事件就会被堵塞在那里,从现象上看得话,就是界面会死掉,如果界面被其他窗口覆盖之后再回到前面的时侯,会变成一片灰色,这是因为PaintEvent被堵塞而不能被分发出去的缘故。
你可以去查下 EventQueue 的工作原理,大概是下面的:
简单来讲,在EventQueue中有一个dispatchThread,这是个线程类,负责事件的分发,当Queue中有事件的时候,他会摘取前面的事件并分发给相应的对象进行处理,等处理完之后再获取下一个,当Queue中没有事件的时候,线程等待。
当有事件触发时,系统会调用EventQueue的push方法将AWTEvent添加到EventQueue的最后,同时唤醒dispatchThread。
为什么界面会死掉
所以能看到,Swing的事件分发实际上是同步的,并且都是在dispatchThread这个线程中处理的,也就是说是个事件一个事件处理的,如果有某一个事件处理的时间非常长的时侯,其他事件就会被堵塞在那里,从现象上看得话,就是界面会死掉,如果界面被其他窗口覆盖之后再回到前面的时侯,会变成一片灰色,这是因为PaintEvent被堵塞而不能被分发出去的缘故。
#4
就是个闭包而已
#5
run里的代码会在将来的某个时间被调用
#6
那为什么不用Thread对象呢?
#7
还不是很明白
#8
也可以用thread对象,thread也实现了Runnable接口
#9
#10
学习了。。
#11
不错,学习中
#12
#13
lz主的问题其实很简单
在java中并不像别的语言那样能直接传入一个代码块,而是传入一个对象
其中:
EventQueue.invokeLater(new Runnable()
{
public void run()
{
....
}
});
的 new Runnable(){run()}只是一种创建对象的简便方式,这样写避免了先创建一个继承Runable接口的
类,然后再创建对象,所以比较简便,在多线程中经常用到。
具体的请看一下面向对象中对面向接口编程的介绍
在java中并不像别的语言那样能直接传入一个代码块,而是传入一个对象
其中:
EventQueue.invokeLater(new Runnable()
{
public void run()
{
....
}
});
的 new Runnable(){run()}只是一种创建对象的简便方式,这样写避免了先创建一个继承Runable接口的
类,然后再创建对象,所以比较简便,在多线程中经常用到。
具体的请看一下面向对象中对面向接口编程的介绍
#14
ls 的理解错了,你说的这种创建对象的简便写法我知道。我现在想问的只是
EventQueue.invokeLater(...)这种写法。这种写法我以前没用过,
我以前用的都是直接创建一个线程对象来做,故请教两者的区别。
EventQueue.invokeLater(...)这种写法。这种写法我以前没用过,
我以前用的都是直接创建一个线程对象来做,故请教两者的区别。
#15
学习了
#16
匿名类
#17
学习!
#18
EventQueue.invokeLater
相当于,定义了一个任务,这个任务在将来的某个时刻被awt线程调用执行。
就好比,放学了,老师给你布置个任务。你回家做。
相当于,定义了一个任务,这个任务在将来的某个时刻被awt线程调用执行。
就好比,放学了,老师给你布置个任务。你回家做。
#19
new Runnable() {} 创建一个“可以被执行”的对象,但这个对象具体什么时候开始执行由EventQueue来决定。
通常你所写的new Thread().start()是创建了这个可执行对象,并且开始执行
通常你所写的new Thread().start()是创建了这个可执行对象,并且开始执行
#20
因为 awt, 或者 swing 为了确保所有的组件是同步的,所以他被设计为单线程的,同一时刻,只有一个线程(事件分发线程,EDT)在操作 组件。所以,要想能正确运行,用户也必须在事件分发线程中操作组件,EventQueue.invokeLater(Runnable),提供了这个方法,让用户的操作在事件分发线程中完成。
#21
其实用Thread类也是可以的,只要你不启动这个Thread,效果和Runnable一样
你可以试一下EventQueue.invokeLater(new Thread() {
public void run() {
....
}
});
你可以试一下EventQueue.invokeLater(new Thread() {
public void run() {
....
}
});
#22
EventQueue定义了一个invokeLater(Runnable instance)方法
调用的时候EventQueue.invokeLater(new Runnable(){public void run(){};})
其中的参数并不是实现创建好的,而是在调用的时候才创建;
也可以EventQueue.invokeLater(runnableInstance);
前提是runnableInstance实现了Runnable接口
调用的时候EventQueue.invokeLater(new Runnable(){public void run(){};})
其中的参数并不是实现创建好的,而是在调用的时候才创建;
也可以EventQueue.invokeLater(runnableInstance);
前提是runnableInstance实现了Runnable接口
#23
这叫闭包吗?
#24
匿名内部类,如果一个类对象,它只使用一次的话,可以这样写
#25
节省代码长度,呵呵,学习!
#1
awt是单线程模式的,所有awt的组件只能在事件处理线程中访问,从而保证组件状态的可确定性。
#2
对于这点我也不是明白
#3
这样是为了防止出现类似于 一个 任务需要大量时间处理时,你的界面不会死掉。
你可以去查下 EventQueue 的工作原理,大概是下面的:
简单来讲,在EventQueue中有一个dispatchThread,这是个线程类,负责事件的分发,当Queue中有事件的时候,他会摘取前面的事件并分发给相应的对象进行处理,等处理完之后再获取下一个,当Queue中没有事件的时候,线程等待。
当有事件触发时,系统会调用EventQueue的push方法将AWTEvent添加到EventQueue的最后,同时唤醒dispatchThread。
为什么界面会死掉
所以能看到,Swing的事件分发实际上是同步的,并且都是在dispatchThread这个线程中处理的,也就是说是个事件一个事件处理的,如果有某一个事件处理的时间非常长的时侯,其他事件就会被堵塞在那里,从现象上看得话,就是界面会死掉,如果界面被其他窗口覆盖之后再回到前面的时侯,会变成一片灰色,这是因为PaintEvent被堵塞而不能被分发出去的缘故。
你可以去查下 EventQueue 的工作原理,大概是下面的:
简单来讲,在EventQueue中有一个dispatchThread,这是个线程类,负责事件的分发,当Queue中有事件的时候,他会摘取前面的事件并分发给相应的对象进行处理,等处理完之后再获取下一个,当Queue中没有事件的时候,线程等待。
当有事件触发时,系统会调用EventQueue的push方法将AWTEvent添加到EventQueue的最后,同时唤醒dispatchThread。
为什么界面会死掉
所以能看到,Swing的事件分发实际上是同步的,并且都是在dispatchThread这个线程中处理的,也就是说是个事件一个事件处理的,如果有某一个事件处理的时间非常长的时侯,其他事件就会被堵塞在那里,从现象上看得话,就是界面会死掉,如果界面被其他窗口覆盖之后再回到前面的时侯,会变成一片灰色,这是因为PaintEvent被堵塞而不能被分发出去的缘故。
#4
就是个闭包而已
#5
run里的代码会在将来的某个时间被调用
#6
那为什么不用Thread对象呢?
#7
还不是很明白
#8
也可以用thread对象,thread也实现了Runnable接口
#9
#10
学习了。。
#11
不错,学习中
#12
#13
lz主的问题其实很简单
在java中并不像别的语言那样能直接传入一个代码块,而是传入一个对象
其中:
EventQueue.invokeLater(new Runnable()
{
public void run()
{
....
}
});
的 new Runnable(){run()}只是一种创建对象的简便方式,这样写避免了先创建一个继承Runable接口的
类,然后再创建对象,所以比较简便,在多线程中经常用到。
具体的请看一下面向对象中对面向接口编程的介绍
在java中并不像别的语言那样能直接传入一个代码块,而是传入一个对象
其中:
EventQueue.invokeLater(new Runnable()
{
public void run()
{
....
}
});
的 new Runnable(){run()}只是一种创建对象的简便方式,这样写避免了先创建一个继承Runable接口的
类,然后再创建对象,所以比较简便,在多线程中经常用到。
具体的请看一下面向对象中对面向接口编程的介绍
#14
ls 的理解错了,你说的这种创建对象的简便写法我知道。我现在想问的只是
EventQueue.invokeLater(...)这种写法。这种写法我以前没用过,
我以前用的都是直接创建一个线程对象来做,故请教两者的区别。
EventQueue.invokeLater(...)这种写法。这种写法我以前没用过,
我以前用的都是直接创建一个线程对象来做,故请教两者的区别。
#15
学习了
#16
匿名类
#17
学习!
#18
EventQueue.invokeLater
相当于,定义了一个任务,这个任务在将来的某个时刻被awt线程调用执行。
就好比,放学了,老师给你布置个任务。你回家做。
相当于,定义了一个任务,这个任务在将来的某个时刻被awt线程调用执行。
就好比,放学了,老师给你布置个任务。你回家做。
#19
new Runnable() {} 创建一个“可以被执行”的对象,但这个对象具体什么时候开始执行由EventQueue来决定。
通常你所写的new Thread().start()是创建了这个可执行对象,并且开始执行
通常你所写的new Thread().start()是创建了这个可执行对象,并且开始执行
#20
因为 awt, 或者 swing 为了确保所有的组件是同步的,所以他被设计为单线程的,同一时刻,只有一个线程(事件分发线程,EDT)在操作 组件。所以,要想能正确运行,用户也必须在事件分发线程中操作组件,EventQueue.invokeLater(Runnable),提供了这个方法,让用户的操作在事件分发线程中完成。
#21
其实用Thread类也是可以的,只要你不启动这个Thread,效果和Runnable一样
你可以试一下EventQueue.invokeLater(new Thread() {
public void run() {
....
}
});
你可以试一下EventQueue.invokeLater(new Thread() {
public void run() {
....
}
});
#22
EventQueue定义了一个invokeLater(Runnable instance)方法
调用的时候EventQueue.invokeLater(new Runnable(){public void run(){};})
其中的参数并不是实现创建好的,而是在调用的时候才创建;
也可以EventQueue.invokeLater(runnableInstance);
前提是runnableInstance实现了Runnable接口
调用的时候EventQueue.invokeLater(new Runnable(){public void run(){};})
其中的参数并不是实现创建好的,而是在调用的时候才创建;
也可以EventQueue.invokeLater(runnableInstance);
前提是runnableInstance实现了Runnable接口
#23
这叫闭包吗?
#24
匿名内部类,如果一个类对象,它只使用一次的话,可以这样写
#25
节省代码长度,呵呵,学习!