Upgrade to Pro — share decks privately, control downloads, hide ads and more …

深いい勉強会 vol.10

FujiKinaga
February 19, 2019

 深いい勉強会 vol.10

FujiKinaga

February 19, 2019
Tweet

More Decks by FujiKinaga

Other Decks in Technology

Transcript

  1. CoroutineΛىಈ͢Δ // UI.kt
 private fun start(block: suspend () -> Unit):

    Job { return uiScope.launch { block() } } 
 // Builders.common.kt public fun CoroutineScope.launch( context: CoroutineContext = EmptyCoroutineContext, start: CoroutineStart = CoroutineStart.DEFAULT, block: suspend CoroutineScope.() -> Unit ): Job { val newContext = newCoroutineContext(context) val coroutine = if (start.isLazy) LazyStandaloneCoroutine(newContext, block) else StandaloneCoroutine(newContext, active = true) coroutine.start(start, coroutine, block) return coroutine } launchͰCoroutine͕ىಈ͢Δ CoroutineContext?
  2. CoroutineContextΛ࡞Δ // CoroutineContext.kt @ExperimentalCoroutinesApi public actual fun CoroutineScope.newCoroutineContext(context: CoroutineContext): CoroutineContext

    { val combined = coroutineContext + context val debug = if (DEBUG) combined + CoroutineId(COROUTINE_ID.incrementAndGet()) else combined return if (combined !== Dispatchers.Default && combined[ContinuationInterceptor] == null) debug + Dispatchers.Default else debug } 
 // Dispatchers.kt public actual val Default: CoroutineDispatcher = createDefaultDispatcher() // CoroutineContext.kt internal actual fun createDefaultDispatcher(): CoroutineDispatcher = if (useCoroutinesScheduler) DefaultScheduler else CommonPool Dispatchers.DefaultΛ࡞Δ CommonPoolΛ࡞Δ
  3. CommonPoolΛ࡞Δ // CommonPool.kt override val executor: Executor get() = pool

    ?: getOrCreatePoolSync() @Volatile private var pool: Executor? = null @Synchronized private fun getOrCreatePoolSync(): Executor = pool ?: createPool().also { pool = it } private fun createPool(): ExecutorService { if (System.getSecurityManager() != null) return createPlainPool() // Reflection on ForkJoinPool class so that it works on JDK 6 (which is absent there) val fjpClass = Try { Class.forName("java.util.concurrent.ForkJoinPool") } ?: return createPlainPool() // Fallback to plain thread pool // Try to use commonPool unless parallelism was explicitly specified or in debug privatePool mode if (!usePrivatePool && requestedParallelism < 0) { Try { fjpClass.getMethod("commonPool")?.invoke(null) as? ExecutorService } ?.takeIf { isGoodCommonPool(fjpClass, it) } ?.let { return it } } // Try to create private ForkJoinPool instance Try { fjpClass.getConstructor(Int::class.java).newInstance(parallelism) as? ExecutorService } ?. let { return it } // Fallback to plain thread pool return createPlainPool() } pool͕nullͳΒCreatePoolSyncΛ࡞Δ pool͕nullͳΒCreatePool createPlainPool͢ΔͱExecutorServiceΛ࡞Δ
  4. createPlainPool()? private fun createPlainPool(): ExecutorService { val threadId = AtomicInteger()

    return Executors.newFixedThreadPool(parallelism) { Thread(it, "CommonPool-worker-$ {threadId.incrementAndGet()}").apply { isDaemon = true } } } public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), threadFactory); } ʂʂʂ ʂʂʂʂʂ
  5. • Thread : Thread.sleep(long)
 - ࢦఆͨ࣌ؒ͠ͷ௕͞ʹΘͨͬͯݱࡏͷεϨο υΛதஅ͠·͢ • Coroutine :

    delay(long)
 - Coroutine಺ͷॲཧΛࢦఆͨ࣌ؒ͠ͷ௕͞ʹ Θͨͬͯதஅ͢Δ
 - suspending function(தஅؔ਺)
  6. delayΛݺͿ // Delay.kt public suspend fun delay(timeMillis: Long) { if

    (timeMillis <= 0) return // don't delay return suspendCancellableCoroutine sc@ { cont: CancellableContinuation<Unit> -> cont.context.delay.scheduleResumeAfterDelay(timeMillis, cont) } } // Executors.kt override fun scheduleResumeAfterDelay(timeMillis: Long, continuation: CancellableContinuation<Unit>) { val future = if (removesFutureOnCancellation) { scheduleBlock(ResumeUndispatchedRunnable(this, continuation), timeMillis, TimeUnit.MILLISECONDS) } else { null } // If everything went fine and the scheduling attempt was not rejected -- use it if (future != null) { continuation.cancelFutureOnCancellation(future) return } // Otherwise fallback to default executor DefaultExecutor.scheduleResumeAfterDelay(timeMillis, continuation) }
  7. scheduleΛBlock // Executors.kt private fun scheduleBlock(block: Runnable, time: Long, unit:

    TimeUnit): ScheduledFuture<*>? { return try { (executor as? ScheduledExecutorService)?.schedule(block, time, unit) } catch (e: RejectedExecutionException) { null } }
  8. • ThreadΫϥε
 - ࠷΋جຊతͳεϨουੜ੒ɾىಈͷΫϥε • RunnableΠϯλʔϑΣʔε
 - εϨου͕࣮ߦ͢Δʮ࢓ࣄʯΛද͢ΠϯλʔϑΣʔε • ThreadFactoryΠϯλʔϑΣʔε


    - εϨουੜ੒Λந৅Խͨ͠ΠϯλʔϑΣʔε • ExecutorΠϯλʔϑΣʔε
 - εϨουͷ࣮ߦΛந৅Խͨ͠ΠϯλʔϑΣʔε • ExecutorServiceΠϯλʔϑΣʔε
 - ࠶ར༻͞ΕΔεϨουͷ࣮ߦΛந৅Խͨ͠ΠϯλʔϑΣʔε • ScheduledExecutorServiceΠϯλʔϑΣʔε
 - εέδϡʔϦϯά͞ΕͨεϨουͷ࣮ߦΛந৅Խͨ͠ΠϯλʔϑΣʔε • ExecutorsΫϥε
 - Πϯελϯεੜ੒ͷϢʔςΟϦςΟΫϥε
  9. • Thread : Thread.sleep(long)
 - εϨουͦͷ΋ͷΛࢭΊ͍ͯΔ • Coroutine : delay(long)


    - ࠶ར༻ՄೳͳεϨουΛ࢖͍·Θͯ࣍͠ͷॲ ཧΛεέδϡʔϦϯά͍ͯ͠Δ