- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
因此,首先,我绝对知道Swing的主要线程安全规则:所有GUI组件交互都必须在事件分发线程上进行。但是,由于我一直在编写代码并按照Model-View-Controller准则进行工作,所以我一直想找到一种方法来解决Swing组件数据模型。
警告,这是一篇很长的文章,但是我想真正地解释一下我的思考过程。我在这里很有创造力,主要是想获得反馈,以了解这是否切实可行。
我现在正在使用的程序现在使用一个 Controller 类,该类实现了ActionListener来监听UI类中组件的事件。调用actionPerformed()方法时,它将通过执行程序将ActionEvent传递到另一个线程,该执行程序在该事件执行程序中解析事件并更新我的程序的模型。这些模型触发PropertyChangeEvent,这些事件包装在SwingUtilities.invokeLater中,因此它们对GUI所做的更改将在EDT上进行。
到目前为止,一切似乎都是100%的犹太洁食。
但是然后我有了这个JList。我要做的是从EDT修改其组件,然后对其进行更新。我已经提出了几个想法,实际上我正在探索实现这一目标的多种途径。特殊的添加/删除PropertyChangeEvents或传递新列表以用每个事件替换现有列表只是我的一些想法。
但是我在这篇文章中提出了我最疯狂的想法:一个线程安全的ConcurrentListModel,可以通过任意数量的线程进行修改,但仍然符合Swing的线程安全规则。
所以,让我解释一下:
对于ListModel,它仅通过三种方式与JList本身进行交互。这些方式中的每一种都为并发访问提出了一个独特的问题:
1)从基础集合(getElement,getSize)中检索信息。 JList需要能够访问基础集合以在其 View 中正确显示其值。此基础集合上的任何同步都可能导致UI的响应性问题,但是如果此集合被多个线程修改,则结果将是任何数量的线程一致性问题。
2)添加/删除ListDataListeners。当然,要添加的监听器是BasicListUI.ListDataHandler,它链接到JList本身。 AbstractListModel实现允许将任意数量的ListDataListeners添加到EventListenerList中。同样,由于响应问题,此列表在EDT需要访问时无法同步,但是如果由多个线程对其进行了修改,则无法保证此列表状态的一致性。
3)触发ListDataEvents。 JList没有链接到模型中的基础集合,只有模型本身。因此,每当模型对基础集合进行更改时,它都必须将ListDataEvent激发到JList。然后,JList调用我前面提到的getElement/size方法。这些事件必须在EDT上触发。
因此,乍一看,这是一个与JList的关系使其无法从EDT进行修改的组件。除了...我是一个固执的SOB,我想我已经找到了解决方法。我将要描述的所有内容,请在做出判断时以任何明显的错误回应。
我列出的三件事,它们不要求ListModel仅由EDT触及,它们仅要求其中的某些部分仅由EDT触及。具体来说,它要求此类的STATE FIELDS(基础列表和EventListenerList)在EDT上保持线程局部。该类的所有方法都以一种或另一种方式与这两个字段进行交互。只要这些方法最终对这些字段产生的影响仅在EventDispatchThread上执行,则调用它们的线程无关紧要。
此外,由于仅在单个线程上修改了类的状态,所以根本不需要任何同步,因为状态字段保持为线程局部的。这样可以避免因Swing组件等待锁定而导致的潜在响应错误。
那么,这一切最终意味着什么?我将展示我的示例代码,以便您可以真正了解我的意思。这是按照我的设计的一个简单的add()方法(注意:我还希望最终产品遵循Collections API和List接口(interface),因此要使用方法签名):
public boolean add(final E element){
final boolean result = false;
if(SwingUtilities.isEventDispatchThread()){
result = swingAdd(element);
}
else{
SwingUtilities.invokeLater(new Runnable(){
@Override
public void run(){
result = swingAdd(element);
}
});
}
return result;
}
private boolean swingAdd(E element){
int index = list.size(); //The current size will be size - 1 after the add, aka the index of the element being added.
boolean result = list.add(element);
fireContentsChanged(this, index, index);
return result;
}
最佳答案
因为这是easy to get wrong,所以建议您使用 java.util.concurrent
提供的现有功能。
对于 JList
的特殊情况,请使用SwingWorker
的实现 Future
来更新ListModel
的实现中的process()
,这将在事件分发线程上调用。使用SwingWorker
的适当实现作为FIFO缓冲区来构造BlockingQueue
。然后,在实现take()
时publish()
和doInBackground()
新到达的元素。请注意,take()
阻止doInBackground()
是可以的;用户不会注意到。现在,您程序中的任何其他线程都可以add()
,offer()
或put()
队列中的元素,并完全确保该元素以最小的等待时间出现在JList
中。
对于您的BlockingQueue
,请考虑为元素的固定大小的缓冲区提供一个ArrayBlockingQueue
。考虑元素的有限大小缓冲区的LinkedBlockingDeque
。如果其他线程可以阻塞,请使用put()
;否则,请使用offer()
。需要检查时使用add()
;并在需要捕获IllegalStateException
的情况下使用ojit_code。
关于java - Java:ConcurrentListModel-试图绕过Swing线程安全规则,我是否陷入困境或发疯,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32039719/
我需要在 nginx-ingress 版本上允许来自多个来源的请求:http://localhost:4200、http://localhost:4242 等1.7.1.但我无法对多个来源执行此操作,
我正在部署我使用 APIGILITY 开发的 API到 IIS。由于 IIS 不支持 .htaccess,我试图从 .htaccess 文件的内容创建 web.config 文件。我使用 IISv7.
我正在尝试更改上面 css 样式中的“宽度”规则。在“inspect element”中你可以看到宽度是1008px。我不希望它是 1008px 但它不会让我在 css 样式中更改它你可以看到它被“删
外部css赋值有2种方法,我用的是第一种;大多数网站使用第二种方法。我想知道我是否做错了! 第一种方法: 为几乎每个 css 规则创建一个类并在任何地方使用它们。 blah blah .f_
RDF使用 WEB 标识符 (URIs) 来标识资源,使用属性和属性值来描述资源 RDF 资源、属性和属性值 RDF使用 WEB 标识符来标识事物,并通过属性和属性值来描述资源。 关于资源、属性
我想挖掘特定的 rhs 规则。文档中有一个示例证明这是可能的,但仅适用于特定情况(如下所示)。先来一个数据集来说明我的问题: input {b=100002} 0.2500000 0.250000
我想让 nginx 从网站根目录(:http://localhost:8080/)提供一个静态文件,但它为我的代理通行证提供服务;它提供“/”规则而不是“=/”。 这是我的 nginx 配置的样子:
根据gnu make documentation , 如果一个规则通过一次调用生成多个目标(例如,一个配方执行一个带有多个输出文件的工具),你可以使用 '&:' 规则语法来告诉 make。但是,当在多
我已阅读Firebase Documentation并且不明白什么是 .contains()。 以下是文档中 Firebase 数据库的示例规则: { "rules": { "rooms"
关闭。这个问题是opinion-based 。目前不接受答案。 想要改进这个问题吗?更新问题,以便 editing this post 可以用事实和引文来回答它。 . 已关闭 6 年前。 Improv
我正在尝试做一些多态性练习,但我无法弄清楚这种多态性是如何工作的。我没有找到任何关于这种练习的深入信息。希望大家能给我一些解释。 练习1: class Top { public void m(
为了调试复杂的 XSLT 转换,我将其分为几个部分:首先构建 %.1.xml,然后使用它构建 %.2.xml ,最后构建 %.3.xml。一切正常,但如果我要求 Make 构建最后一个,Make 总是
我尝试了 hacerrank 的 slove 练习 Click我不知道如何添加这些规则: ► 它可以包含 4 个一组的数字,并用一个连字符“-”分隔。 ► 不得有 4 个或更多连续重复数字。 这是我的
我正在尝试编写一个小测验,我希望“再试一次”按钮遵循与“else”之前的“if”语句相同的规则 using System; public class Program { public stat
在我的 Spring/Boot Java 项目中,我有一组服务方法,例如以下一个: @Override public Decision create(String name, String descr
我正在阅读 Covariant virtual function .上面写着 假设 B::f 覆盖了虚函数 A::f。如果满足以下所有条件,A::f 和 B::f 的返回类型可能不同: 1) The
我工作的公司想要分发(在公共(public)链接中)具有内部签名的应用程序。我很确定 Apple 否认这种事情,但我在官方文档/契约(Contract)中没有找到任何相关信息。 有谁知道它到底是如何工
我是 CSS 新手。我观察到一个奇怪的 CSS 行为,其中一个元素具有以下 CSS 属性 .container .header{ color: #FFFFFF; font-size: 2em;
这个问题在这里已经有了答案: Is there a CSS selector for elements containing certain text? (21 个答案) 关闭 7 年前。
我有以下 CSS: workoutcal.css: .errorlist{ color:red; } 以下基本模板: base.html: {% load static %} {
我是一名优秀的程序员,十分优秀!