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

深いい勉強会 vol.10

Sponsored · SiteGround - Reliable hosting with speed, security, and support you can count on.
Avatar for FujiKinaga FujiKinaga
February 19, 2019

 深いい勉強会 vol.10

Avatar for FujiKinaga

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)


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