我正在构建一个java应用程序,并且我已经实现了自定义的侦听器和事件。现在的问题是,有许多事件和侦听器,在侦听器处理事件时,应用程序GUI线程被阻塞。这个问题可以用事件分派线程来解决吗?如果是这样的话,是怎么做的?
监听器的代码:
public class ProjectChangeObserver
{
private List<ProjectChangeListener> listeners = new ArrayList<ProjectChangeListener>();
public void addProjectChangeListener(ProjectChangeListener l)
{
listeners.add(l);
}
public void removeProjectChangeListener(ProjectChangeListener l)
{
listeners.remove(l);
}
public void removeAllProjectChangeListeners()
{
listeners.clear();
}
public void fireProjectChange(ProjectChangeEvent e)
{
if(listeners.size() > 0)
{
ArrayList<ProjectChangeListener> safeCopy = new ArrayList<ProjectChangeListener>(listeners);
for (ProjectChangeListener cl : safeCopy ) {
cl.onProjectChange(e);
}
}
}
}发布于 2012-07-30 18:57:27
Swing的一个特性是它是single-threaded。
但是,没有什么可以阻止您生成自己的线程来进行后台处理。只要您只调用revalidate()或repaint(),那么所有绘图仍将在Swing线程中处理。
(请记住,如果您要派生其他线程来执行后台工作,那么如果您希望Swing线程看到与您的线程中相同的值,请确保将变量声明为volatile。或者通过另一个监听程序将信息传回。)
如果您打算在单独的线程中进行绘制本身(例如,自定义组件),那么根据具体情况,这是不可能的,或者是非常不鼓励的。(某些特殊情况可能允许在自定义线程安全缓冲类中使用多CPU生成场景,但您不太可能这样做)。
如果您发现您的Listener是CPU/网络密集型的,那么您可能需要考虑谁在呼喊,谁在倾听的体系结构。我总是试图最小化我的“视图”代码中的呼叫量,以便它只对事件做出响应。
顺便说一句,我发现Project Lombok和它的测试版姐妹Lombok PG大大减少了用@ListenerSupport实现Listener模式的模板。
发布于 2012-07-30 18:47:26
相反,这必须解决避免事件分派线程(“GUI线程”只是相同的东西的另一个名称)。必须使用SwingWorker在其自己的线程中启动异步任务。
发布于 2012-07-30 19:28:16
如果要防止UI阻塞,则应为事件运行单独的线程。
如果您想要为事件使用单个线程,那么您可以创建线程,并且可以使用存储事件的队列将命令传递给事件线程。
但是如果可能的话,你应该为你的事件打开异步线程,并且你应该确保在需要的时候刷新UI。
https://stackoverflow.com/questions/11719844
复制相似问题