【问题标题】:Android: Sharing lists between two threadsAndroid:在两个线程之间共享列表
【发布时间】:2015-07-29 09:57:30
【问题描述】:

我正在做一个应用程序,其中有 2 个从 SurfaceView 扩展的视图,称为 CanvasView。

我有一个左侧 CanvasView 和一个右侧 CanvasView。 这两个 CanvasView 都实例化了一个 UIThread,它从 Thread 扩展而来。 CanvasView 本身像这样传递到线程中:

public void surfaceCreated(SurfaceHolder holder) {
  uiThread = new UIThread(this);
  uiThread.setRunning(true);
  uiThread.start(); 
}

在每个 CanvasView 的 onDraw() 中,我都会访问一个列表。该列表基本上由要绘制的内容列表组成,在左右画布上基本相同。

for (CharSequence line : lineList) {
... 
..
}

每当我的应用需要在 lineList 中绘制项目时,它都会崩溃说 java.util.ConcurrentModificaitonException。

在两个线程之间“共享”Arraylist lineList 的正确方法是什么?

谢谢。

【问题讨论】:

    标签: java android multithreading arraylist


    【解决方案1】:

    列表不是线程安全的,当多个线程尝试修改同一个列表时,会出现并发修改异常。

    使用ConcurrentLinkedQueueCopyOnWriteArrayList

    参考链接 - Is there a concurrent List in Java's JDK?

    Collections.synchronizedList() 是另一种替代方法,它将提供对列表的同步访问。

    【讨论】:

    • 感谢我的问题已使用 CopyOnWriteArrayList 和 Erm 解决,而不是使用这么多线程 XD
    • 嗨@lppier,您在onDraw 中使用CopyOnWriteArrayList。你没有性能问题吗?
    • @JasonChueh 没有注意到任何事情,有替代方案吗?
    • @lppier,我只是想知道您是否遇到任何问题。如果没有,这应该是一个很好的解决方案:)
    【解决方案2】:

    ArrayList 类不是 Thread Safe

    使用Collections.synchronizedList() 而不是ArrayList

    【讨论】:

      【解决方案3】:

      不要使用 for 循环的简化版本

      for (CharSequence line : lineList) {
          ... 
          ..
      }
      

      改为使用传统的。但是,您必须自己处理数据一致性。

      for (int i = 0; i < lineList.size(); i++) {
          CharSequence line = lineList.get(i)
          ..
      }
      

      【讨论】:

      • 嗨,Jason,对不起,这两者有什么区别?
      • 第一个是编译器糖。由于列表是一个集合,编译器使用迭代器翻译 for 循环。迭代器是抛出异常的人。但是,如果将数据存储在数组中,则不会引发异常。如果您的数据是一个简单的数组,编译器将使用常规的 for 循环。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-12
      • 1970-01-01
      • 1970-01-01
      • 2015-11-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多