Kotlin协程:等待多个线程完成

Kotlin协程:等待多个线程完成,kotlin,coroutine,kotlin-coroutines,Kotlin,Coroutine,Kotlin Coroutines,因此,第一次看协程,我想并行处理一个数据负载,并等待它完成。我环顾四周,看到RunBlocking和Wait等,但不知道如何使用它 到目前为止,我已经做到了 val jobs = mutableListOf<Job>() jobs += GlobalScope.launch { processPages(urls, collection) } jobs += GlobalScope.launch { processPages(urls, collection2) } jobs +=

因此,第一次看协程,我想并行处理一个数据负载,并等待它完成。我环顾四周,看到RunBlocking和Wait等,但不知道如何使用它

到目前为止,我已经做到了

val jobs = mutableListOf<Job>()
jobs += GlobalScope.launch { processPages(urls, collection) }
jobs += GlobalScope.launch { processPages(urls, collection2) }
jobs += GlobalScope.launch { processPages(urls, collection3) }
val jobs=mutableListOf()
jobs+=GlobalScope.launch{processPages(URL,集合)}
jobs+=GlobalScope.launch{processPages(URL,collection2)}
jobs+=GlobalScope.launch{processPages(URL,collection3)}

然后我想知道/等待它们完成

您可以使用
async
builder函数并行处理数据负载:

class Presenter {
    private var job: Job = Job()
    private var scope = CoroutineScope(Dispatchers.Main + job) // creating the scope to run the coroutine. It consists of Dispatchers.Main (coroutine will run in the Main context) and job to handle the cancellation of the coroutine.

    fun runInParallel() {
        scope.launch { // launch a coroutine
            // runs in parallel
            val deferredList = listOf(
                    scope.asyncIO { processPages(urls, collection) },
                    scope.asyncIO { processPages(urls, collection2) },
                    scope.asyncIO { processPages(urls, collection3) }
            )

            deferredList.awaitAll() // wait for all data to be processed without blocking the UI thread

            // do some stuff after data has been processed, for example update UI
        }
    }

    private fun processPages(...) {...}

    fun cancel() {
        job.cancel() // invoke it to cancel the job when you don't need it to execute. For example when UI changed and you don't need to process data
    }
}
扩展功能
asyncIO

fun <T> CoroutineScope.asyncIO(ioFun: () -> T) = async(Dispatchers.IO) { ioFun() } // CoroutineDispatcher - runs and schedules coroutines
fun CoroutineScope.asyncIO(ioFun:()->T)=async(Dispatchers.IO){ioFun()}//CoroutineDispatcher-运行和调度协同路由
GlobalScope.launch
除非您希望协同程序在整个应用程序生命周期内运行,并且不希望过早取消


编辑:正如Roman Elizarov所说,除非您想在处理完所有数据后立即更新UI或做其他事情,否则您可以尝试不使用
awaitAll()
函数。

如果您使用结构化并发的概念,您不需要手动跟踪当前作业。假设您的
processPages
函数执行某种阻塞IO,您可以将代码封装到以下挂起函数中,该函数在为此类工作设计的IO调度程序中执行您的代码:

suspend fun processAllPages() = withContext(Dispatchers.IO) { 
    // withContext waits for all children coroutines 
    launch { processPages(urls, collection) }
    launch { processPages(urls, collection2) }
    launch { processPages(urls, collection3) }
}
现在,如果应用程序最顶层的函数还不是挂起函数,那么您可以使用
runBlocking
调用
processAllPages

runBlocking {
    processAllPages()
}

可以使用以下方法

fun myTask() {
    GlobalScope.launch {
        val task = listOf(
            async {

            },
            async {

            }
        )
        task.awaitAll()

    }
}

不需要
async
,因为这里不使用结果。也不需要执行
waitAll
,因为外部协同路由会等待所有的子线程。我在线程“main”java.lang.NoClassDefFoundError中遇到异常:kotlin/coroutines/jvm/internal/CoroutineImpl at java.lang.ClassLoader.defineClass1(本机方法)@Burf2000我想这是因为使用了
Dispatchers.main
。请检查指南,用合适的调度程序替换它。我将其更改为默认值,确保我有最新的协同程序框架,并且所有东西都运行良好。实际上这不起作用,var processor=processor()processor.runInParallel()println(“完成”)是否立即打印此操作是否并行运行所有作业?我正在获取支持函数processAllPages(),该函数只能从另一个协程或支持发送调用function@Burf2000在runBlocking方法内调用processAllPages()。