![](/img/trans.png)
[英]How do I kill a long-running servlet process from another servlet?
[英]How do I update a JTable based on a notification received from a long-running task in other thread?
我有一个Observer TableModel,它监听在数据库中执行的一些更改,然后调用下面的更新方法。 我的问题是,我应该如何防止错误:
java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
at java.util.ArrayList.RangeCheck(ArrayList.java:547)
at java.util.ArrayList.set(ArrayList.java:337)
at com.mysimpatico.memoplatform.persistenceui.MeaningsViewerTopComponent$DefaultTableModelImpl.update(MeaningsViewerTopComponent.java:108)
我不知道SwingWorker会如何提供帮助。 我在一个单独的线程中执行长时间运行的数据库任务,但是这会在Observable类中调用一个方法(数据库持久化)来通知观察者。
@Override
public void update(Observable o, final Object arg) {
final Meaning meng = (Meaning) arg;
final int row;
final boolean insert;
synchronized (mengs) {
if (mengs.contains(meng)) {
row = meng.getObjId();
mengs.set(row, meng);
insert = false;
} else {
row = mengs.size();
mengs.add(row, meng); //last
insert = true;
}
try {
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
if (insert) {
fireTableRowsInserted(row, row);
} else {
fireTableRowsUpdated(row, row);
}
}
});
} catch (InterruptedException ex) {
Exceptions.printStackTrace(ex);
} catch (InvocationTargetException ex) {
Exceptions.printStackTrace(ex);
}
}
}
尽管在事件调度线程上触发插入/更新TableModelEvent
,但实际上在执行数据库更新通知的任何线程上都会更新TableModel
。 这很危险,因为它意味着:
TableModel
处于不一致状态。 TableModel
因为通知线程正在改变它。 解决方案应该(理论上)只是将您对SwingUtilities.invokeAndWait
的调用移到开始的代码块之外: synchronized(mengs)
。 此外,一旦完成此操作,您实际上可以完全删除synchronized关键字,因为对模型的所有访问都将在EDT上完成。
Observable
我会避免使用Observer
/ Observable
类(有关更多信息,请参阅我对此问题的回答 ); 更好地定义特定于域的侦听器接口和事件类(子类java.util.EventObject
)。
你的索引是否正确?
java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
上面的语句说你只在数组列表中有一个条目。 我不知道你的代码是“添加”还是“更新”。 但请记住,ResultSet索引是基于1而不是基于0,所以可能需要从所有行值中减去1?
一种选择是使用org.jdesktop.application.Task
。 您需要将TableModel
传递给Task,然后再进行简单的TableModel.insert
调用。
注意:任务只是围绕Thread的一个很好的包装器。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.