Мьютекс не останавливает более одной сопрограммы для изменения или чтения данных.Android

Форум для тех, кто программирует под Android
Ответить
Гость
 Мьютекс не останавливает более одной сопрограммы для изменения или чтения данных.

Сообщение Гость »


I have a service that holds a list of trains (important data that I want to share between coroutines). It also has methods to modify the list. So, I use mutex in these methods.
This is the code that calls the methods (it is inside a coroutine):

Код: Выделить всё

val contours: List = ArrayList()
val hierarchy = Mat()

Imgproc.findContours(result, contours, hierarchy, Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE)

Imgproc.cvtColor(result, result, Imgproc.COLOR_GRAY2BGR)

for (contour in contours) {
if (contour.toArray().size > 100) {
val mask = Mat.zeros(foreground.size(), CvType.CV_8UC1)
val white = Scalar.all(255.0)
Imgproc.drawContours(mask, listOf(contour), -1, white, -1)

val meanColor = Core.mean(foreground, mask)

trainService.addTrain(contour, meanColor)

Imgproc.drawContours(result, listOf(contour), -1, meanColor, FILLED)
} else {
Imgproc.drawContours(result, listOf(contour), -1, Scalar(0.0, 0.0, 0.0), FILLED)
}
}

trainService.removeUnusedTrains()

val resultBitmap =
Bitmap.createBitmap(result.width(), result.height(), Bitmap.Config.ARGB_8888)
Utils.matToBitmap(result, resultBitmap)
This is the train service

Код: Выделить всё

class TrainService {
private var trains : MutableList = emptyList().toMutableList()

private val mutex = Mutex()

suspend fun addTrain(newTrain: MatOfPoint, trainColor: Scalar) = mutex.withLock {
for(train in trains) {
when {
train.isSame(newTrain) -> return true
}
}
val train = Train(newTrain, trainColor)
trains.add(train)
}

suspend fun removeUnusedTrains() = mutex.withLock {
for(train in trains) {
if (!train.changed) {
trains.remove(train)
} else {
train.changed = false
}
}
Log.d("TrainService", "Trains now: ${trains.joinToString()}")
}
}
I expect that to lock it so only one at the time can modify or read the list.
But when I try to run it I get this error:

Код: Выделить всё

time: 1709989371723
msg: java.util.ConcurrentModificationException
stacktrace: java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.next(ArrayList.java:860)
at com.xcerna11.traincontroller.TrainService.removeUnusedTrains(TrainService.kt:25)
at com.xcerna11.traincontroller.OpenCVDetector$run$2.invokeSuspend(OpenCVDetector.kt:74)
at com.xcerna11.traincontroller.OpenCVDetector$run$2.invoke(Unknown Source:8)
at com.xcerna11.traincontroller.OpenCVDetector$run$2.invoke(Unknown Source:4)
at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturn(Undispatched.kt:89)
at kotlinx.coroutines.CoroutineScopeKt.coroutineScope(CoroutineScope.kt:264)
at com.xcerna11.traincontroller.OpenCVDetector.run(OpenCVDetector.kt:24)
at com.xcerna11.traincontroller.TrainAnalyzer$analyze$1$1.invokeSuspend(TrainAnalyzer.kt:20)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:284)
at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:85)
at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:59)
at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source:1)
at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:38)
at kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source:1)
at com.xcerna11.traincontroller.TrainAnalyzer.analyze(TrainAnalyzer.kt:19)
at androidx.camera.core.ImageAnalysis.lambda$setAnalyzer$2(ImageAnalysis.java:528)
at androidx.camera.core.ImageAnalysis$$ExternalSyntheticLambda2.analyze(D8$$SyntheticClass:0)
at androidx.camera.core.ImageAnalysisAbstractAnalyzer.lambda$analyzeImage$0$androidx-camera-core-ImageAnalysisAbstractAnalyzer(ImageAnalysisAbstractAnalyzer.java:286)
at androidx.camera.core.ImageAnalysisAbstractAnalyzer$$ExternalSyntheticLambda0.run(D8$$SyntheticClass:0)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1137)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)
at java.lang.Thread.run(Thread.java:1012)


Источник: https://stackoverflow.com/questions/781 ... d-the-data
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Android»