【问题标题】:Still getting concurrent modification exception with synchronizedList仍然使用同步列表获得并发修改异常
【发布时间】:2020-08-12 06:56:17
【问题描述】:

Gretiings,我之前问过这个问题,但即使在更改之后我仍然收到并发修改异常,我已经实现了 synchronizedList 和 synchronized(list) 但异常仍然发生,我没有想法了,可以你给一些建议还有什么可能发生的?谢谢

manager.getMutableList()
        .observe(viewLifecycleOwner, Observer { queueList ->
            Collections.synchronizedList(ArrayList<Object>()).apply {
                this.addAll(queueList)
                synchronized(this) {
                    if (this.isNotEmpty()) {
                        // Do Something
                    } else {
                        // Do other stuff
                    }

                    (recyclerView.adapter as Adapter).run {
                        items = this@apply
                        notifyDataSetChanged()
                        hideLoadingScreen()
                    }
                }
            }
        })

这是异常的痕迹

Fatal Exception: java.util.ConcurrentModificationException
   at java.util.ArrayList$SubList.size(ArrayList.java:1057)
   at java.util.AbstractCollection.toArray(AbstractCollection.java:136)
   at java.util.ArrayList.addAll(ArrayList.java:588)
   at java.util.Collections$SynchronizedCollection.addAll(Collections.java:2089)
   at com.sample.app.ui.Fragment$setObservers$6.onChanged(Fragment.java:382)
   at com.sample.app.ui.Fragment$setObservers$6.onChanged(Fragment.java:89)
   at androidx.lifecycle.LiveData.considerNotify(LiveData.java:131)
   at androidx.lifecycle.LiveData.dispatchingValue(LiveData.java:144)
   at androidx.lifecycle.LiveData$ObserverWrapper.activeStateChanged(LiveData.java:443)
   at androidx.lifecycle.LiveData$LifecycleBoundObserver.onStateChanged(LiveData.java:395)
   at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.java:361)
   at androidx.lifecycle.LifecycleRegistry.forwardPass(LifecycleRegistry.java:300)
   at androidx.lifecycle.LifecycleRegistry.sync(LifecycleRegistry.java:339)
   at androidx.lifecycle.LifecycleRegistry.moveToState(LifecycleRegistry.java:145)
   at androidx.lifecycle.LifecycleRegistry.handleLifecycleEvent(LifecycleRegistry.java:131)
   at androidx.fragment.app.FragmentViewLifecycleOwner.handleLifecycleEvent(FragmentViewLifecycleOwner.java:51)
   at androidx.fragment.app.Fragment.performStart(Fragment.java:2737)
   at androidx.fragment.app.FragmentStateManager.start(FragmentStateManager.java:365)
   at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1194)
   at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1356)
   at androidx.fragment.app.FragmentManager.moveFragmentToExpectedState(FragmentManager.java:1434)
   at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:442)
   at androidx.fragment.app.FragmentManager.executeOps(FragmentManager.java:2169)
   at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1992)
   at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1947)
   at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1849)
   at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2629)
   at androidx.fragment.app.FragmentManager.dispatchStart(FragmentManager.java:2583)
   at androidx.fragment.app.Fragment.performStart(Fragment.java:2739)
   at androidx.fragment.app.FragmentStateManager.start(FragmentStateManager.java:365)
   at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1194)
   at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1356)
   at androidx.fragment.app.FragmentManager.moveFragmentToExpectedState(FragmentManager.java:1434)
   at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1497)
   at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2625)
   at androidx.fragment.app.FragmentManager.dispatchStart(FragmentManager.java:2583)
   at androidx.fragment.app.Fragment.performStart(Fragment.java:2739)
   at androidx.fragment.app.FragmentStateManager.start(FragmentStateManager.java:365)
   at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1194)
   at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1356)
   at androidx.fragment.app.FragmentManager.moveFragmentToExpectedState(FragmentManager.java:1434)
   at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1497)
   at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2625)
   at androidx.fragment.app.FragmentManager.dispatchStart(FragmentManager.java:2583)
   at androidx.fragment.app.FragmentController.dispatchStart(FragmentController.java:258)
   at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:550)
   at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:210)
   at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1419)
   at android.app.Activity.performStart(Activity.java:7479)
   at android.app.ActivityThread.handleStartActivity(ActivityThread.java:3454)
   at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:180)
   at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:165)
   at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:142)
   at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:70)
   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2199)
   at android.os.Handler.dispatchMessage(Handler.java:112)
   at android.os.Looper.loop(Looper.java:216)
   at android.app.ActivityThread.main(ActivityThread.java:7625)
   at java.lang.reflect.Method.invoke(Method.java)
   at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:987)

【问题讨论】:

  • 在 com.sample.app.ui.Fragment$setObservers$6.onChanged(Fragment.java:382) 在 com.sample.app.ui.Fragment$setObservers$6.onChanged(Fragment.java: 89)这些线路上有什么?
  • 第382行是代码段的this.addAll(queueList),第89行是Fragment类开始的地方class Fragment: Fragment() {
  • 我怀疑你正在从不同的线程(在你的manager)修改原始queueList

标签: android kotlin collections observable concurrentmodification


【解决方案1】:

在我看来,您正在锁定“this”,这是每次执行的唯一列表。您应该锁定一个共享对象,例如 queueList。

【讨论】:

  • 但是如果我在 synchronizedList 上检查 isEmpty 条件,这表示 this 处于可锁定状态,我为什么要锁定我最初克隆的原始列表?
  • 我正在阅读可能会使用 CopyOnWriteArrayList 而不是 Collections.synchronizedList,并删除列表的锁定
  • 每个进入这里的线程都会创建一个可变列表的副本。您正在锁定该副本,但是由于每个线程都有自己的副本,因此您永远不会阻塞任何东西。同步没有效果。如果您锁定 queueList,则没有两个线程可以同时到达“做某事”。
猜你喜欢
  • 2012-11-21
  • 1970-01-01
  • 2012-09-26
  • 2016-11-19
  • 2013-03-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多