Почему Executor.asCoroutineDispatcher не работает как newFixedThreadPoolContext? - PullRequest
0 голосов
/ 19 декабря 2018

Я думал, что эти две строки будут эквивалентны в плане выполнения:

val context1 = Executors.newFixedThreadPool(2).asCoroutineDispatcher()
val context2 = newFixedThreadPoolContext(2, "Fixed")

Но когда я использую "context2" в приведенном ниже коде, он работает как положено, но "context1" действует как один поток.

val context1 = Executors.newFixedThreadPool(2).asCoroutineDispatcher()

repeat(4) {
    launch {
        withContext(context1) {
            Thread.sleep(2000)
        }
    }
}

context1.close()

Ожидается : 2 потока будут выполняться параллельно.Код должен завершиться за 4 секунды, потому что 2 потока спят в течение 2 секунд, а затем повторяются.

Actual : выполняется только один поток, и "repeat" выполняется последовательно, что занимает 8секунд до завершения.

Это ошибка?

Или что подразумевается под этой документацией здесь ?

Если вам нужен совершенно отдельный пул потоков с политикой планирования, основанной на стандартном JDKexecutors, используйте следующее выражение: Executors.newFixedThreadPool (). asCoroutineDispatcher ().

1 Ответ

0 голосов
/ 20 декабря 2018

После игры с полным примером кода:

import kotlinx.coroutines.*
import java.util.concurrent.Executors

fun log(msg: String) = println("[${Thread.currentThread().name}] $msg")


fun main() = runBlocking {
    val context1 = Executors.newFixedThreadPool(2).asCoroutineDispatcher()
    val context2 = newFixedThreadPoolContext(2, "Fixed")

    repeat(4) {
        launch {
            withContext(context1) {
                log("Start sleep $it")
                Thread.sleep(2000)
                log("Finished sleep $it")
            }
        }
    }

//    context1.close()
}

Я обнаружил, что проблема в "context1.close ()".Если я закомментирую "context1.close ()", он будет работать правильно.Я предполагаю, что вызовы "launch" не блокируются, поэтому "context1.close ()" выполняется до того, как "withContext" выполняется в других потоках.Я бы предположил, что это приведет к ошибке, но, похоже, это просто сделает его одним потоком.

...