【发布时间】:2019-06-27 16:50:24
【问题描述】:
我正在编写一个使用两个线程的 Java 程序,一个是不断迭代小部件的 ArrayList 并更新它们的状态,第二个是一个线程利用 swing 根据小部件的状态为一系列块设置动画。
我的问题是如何让实现 Runnable 接口的 Painter 查看 WidgetManager 拥有的小部件的数组列表?此外,这种模式是否天生就有缺陷?我被教导要避免使用全局变量(例如在 main 中定义 WidgetList),但据我了解,没有办法将引用传递给 Runnable 线程,因为 run() 方法不需要依赖注入。
main{
WidgetManager wm;
Painter painter;
painter.run();
wm.updateWidgets();
}
public class WidgetManager{
volatile ArrayList<Widget> widgets;
void updateWidgets(){
while(true){
//do some stuff
}
}
}
public class Painter implements Runnable{
public void run(){
//paint some stuff
}
}
【问题讨论】:
-
在主要:painter.setWidgets(wm.getWidgets());
-
除了可以为
Painter提供setWidgets方法之外,您还可以给它一个带参数的构造函数,在构造时接收任意内容。Painter实现Runnable以定义Thread类的协定。这并不意味着您的应用程序不能像Painter的实例一样使用Painter——这是您控制的一个类。但除此之外,你的方法行不通。将引用ArrayList的字段声明为volatile,并不能神奇地使ArrayList(以及您使用它的方式)线程安全。 -
感谢@Holger 关于线程安全问题的意见。我仍在尝试学习多线程,所以当我不知道某些事情时知道它很有用。您是否有任何特定的资源/关键术语建议我研究以维护此类操作的线程安全?我最初是在考虑使用某种锁定,但我认为在画家检查数组时锁定数组与根本不使用多线程基本上是一样的。
-
绘画过程中的锁定不必那么糟糕。这取决于更新列表的频率以及更新需要多长时间。换句话说,这取决于锁定实际上导致阻塞的可能性有多大。如果更新发生得太频繁而无法使锁定可行,则在不同的列表上执行更新并在完成后交换列表可能是更好的选择。 “Java 并发实践”,ISBN:978-0321349606 可能会有所帮助。
标签: java multithreading swing concurrency object-oriented-analysis