【问题标题】:Avoiding use of global variable while allowing access to object owned by another thread避免使用全局变量,同时允许访问另一个线程拥有的对象
【发布时间】: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


【解决方案1】:

...run() 方法不需要 [参数]

run() 方法由interface 定义。您可以使用implements(注意,不是extends)接口的任何类的实例来创建线程。你的类可以有实例变量...

public class Painter implements Runnable{
  private ArrayList<Widget> widgets;
  public Painter(ArrayList<Widget> widgets) {
      this.widgets = widgets;
  }
  public void run(){
     paintSomeStuffBasedOnContentOf(widgets);
  }
}

【讨论】:

  • 感谢您的回复!一个问题:这个实现不会导致 WidgetPainter 接收到 WidgetPainter 实例化时存在的小部件数组的单个副本吗?意思是,当我 WidgetManager 更新小部件时,WidgetPainter 不会看到这些更新?
  • 您问,“...访问另一个线程拥有的对象”,所以我没有编写任何可以复制数组的代码。为了使用我的示例中的Painter 版本,您必须在调用构造函数时传递对ArrayList&lt;Widget&gt; 对象的引用。然后,新的painter 对象将保持其对相同 ArrayList. 的引用。
猜你喜欢
  • 1970-01-01
  • 2012-12-19
  • 2022-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-13
相关资源
最近更新 更多