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

scala_multi_thread.pdf

Avatar for fuzyco fuzyco
July 19, 2018

 scala_multi_thread.pdf

Avatar for fuzyco

fuzyco

July 19, 2018
Tweet

More Decks by fuzyco

Other Decks in Programming

Transcript

  1. 5 ϚϧνεϨουؔ࿈༻ޠ ‣ ഉଞ੍ޚ ‣ εϨουηʔϑ ‣ ΞτϛοΫʢෆՄ෼ૢ࡞ʣ ෳ਺ͷτϥϯβΫγϣϯ͔Βಉ͡Ϧιʔεʹରͯ͠ɺ ಉ࣌ʹߋ৽ॲཧ͕ߦΘΕΔࡍʹɺσʔλͷ੔߹ੑΛอͭͨΊʹߦ͏ॲཧ

    ϚϧνεϨουͰಈ࡞ͤͯ͞΋໰୊ͷͳ͍ϓϩάϥϜͷ͜ͱ(σουϩοΫɺσʔλڝ߹͕ى͖ͳ͍) ଞͷεϨουʹ͸ׂΓࠐΈΛͤͣ͞ɺݱࡏߦ͍ͬͯΔมߋૢ࡞͕࣮֬ʹऴΘͬͨޙʹ࣮ߦͰ͖Δ͜ͱ
  2. 9 ϚϧνεϨουͷ࢓૊Έ εϨου1 ϝΠϯϝϞϦ εϨου2 ಡΈࠐΈ ಡΈࠐΈ ॻ͖ࠐΈ Ճࢉ •

    ࣮ߦޮ཰Λ͋͛ΔͨΊʹɺ֤εϨου͸࡞ۀ༻ϝϞϦΛ͍࣋ͬͯΔ • جຊ͸࡞ۀ༻ϝϞϦʹରͯ͠ಡΈॻ͖͕ߦΘΕɺ ద౰ͳλΠϛϯάͰϝΠϯϝϞϦ΁ಉظ͢Δ ίϐʔ ಉظ ಉظ ίϐʔ
  3. 11 Volatileम০ࢠ͕ղܾ͢Δ͜ͱ εϨου1 ϝΠϯϝϞϦ εϨου2 ಡΈࠐΈ ಡΈࠐΈ ॻ͖ࠐΈ ॻ͖ࠐΈ Ճࢉ

    Ճࢉ Volatileम০ࢠʹΑͬͯ௚઀ϝΠϯϝϞϦʹ อଘ͢Δ͜ͱʹΑͬͯɺ๷͙
  4. 15 Synchronizedम০ࢠ Volatileम০ࢠʹ͸ͳ͍ϩοΫػߏΛ༻͍ͯɺ ΦϒδΣΫτ΍ϝιουʹରͯ͠ϩοΫΛ഑ஔ͢Δ͜ͱʹΑͬͯɺ ಉ࣌ʹෳ਺ͷεϨου͕ॲཧΛߦΘͳ͍Α͏ʹഉଞ੍ޚΛߦ͏ def process() = synchronized {

    // ϝιουʹର͢Δഉଞ੍ޚ } def process() = obj.synchronized { // ΦϒδΣΫτʹର͢Δഉଞ੍ޚ } ࢖͍͜ͳͤΕ͹ɺෳࡶͳॲཧ΋҆શʹߦ͑Δ
  5. 17 SynchronizedϢʔεέʔε ෳ਺ͷεϨου͕ಉ࣌ʹॻ͖ࠐΈʹߦ͘ def add(account: Account, n: Int) = {

    account.money += n Thread.sleep(1000) println(s"thread: ${Thread.currentThread().getId()}, money: ${account.money}") } val jane = new Account("Jane", 100) val t1 = thread { add(jane, 10) } // εϨου1 val t2 = thread { add(jane, 70) } // εϨου2 t1.join(); t2.join() class Account(val name: String, var money: Int) ————————————————————————— thread: 1, money: 180 thread: 2, money: 180 εϨου1͕moneyΛදࣔ͢Δલʹɺ εϨου2͕moneyΛߋ৽͍ͯ͠Δ
  6. 18 accountΦϒδΣΫτʹରͯ͠ϩοΫΛ͔͚ͯɺ ̍εϨου୯ҐͰ͔ͦ͠ͷaccountΦϒδΣΫτʹ ΞΫηεͰ͖ͳ͍Α͏ʹ͍ͯ͠Δ def add(account: Account, n: Int) =

    account.synchronized { account.money += n Thread.sleep(1000) println(s"thread: ${Thread.currentThread().getId()}, money: ${account.money}") } val jane = new Account("Jane", 100) val t1 = thread { add(jane, 10) } // εϨου1 val t2 = thread { add(jane, 70) } // εϨου2 t1.join(); t2.join() class Account(val name: String, var money: Int) —————————————————————————- thread: 1, money: 110 thread: 2, money: 180 ֤εϨου͕ஞ࣍తʹॲཧΛߦ͍ͬͯΔ SynchronizedϢʔεέʔε
  7. 19 Synchronizedͷ໰୊఺ def send(a: Account, b: Account, n: Int) =

    a.synchronized { b.synchronized { a.money -= n b.money += n } } val a = new Account("Jack", 1000) val b = new Account("Jill", 2000) val t1 = thread { for(i <- 0 until 100) send(a, b, 1) } // εϨου1 val t2 = thread { for(i <- 0 until 100) send(b, a, 1) } // εϨου2 t1.join(); t2.join() σουϩοΫ ͓ޓ͍͕ϩοΫΛղ์͞ΕΔͷΛ଴ͬͯ͠·͏
  8. 25 Atomicม਺ Volatileम০ࢠͷ͍ͭͨม਺ʹର͢Δ ΠϯΫϦϝϯτॲཧ͸ΞτϛοΫʹͳΒͳ͍ private val LOOP = 100000000 //

    1ԯճϧʔϓ @volatile private var counter = 0L def count() = { for { i <- 1 to LOOP } counter += 1 } val t1 = thread { count() } // εϨου1 val t2 = thread { count() } // εϨου2 t1.join(); t2.join() println(s"counter: ${counter}”) ———————————————————— counter: 101280698 private val LOOP = 100000000 // 1ԯճϧʔϓ private val counter = new AtomicLong(0L) def count() = { for { i <- 1 to LOOP } counter.getAndIncrement() } val t1 = thread { count() } // εϨου1 val t2 = thread { count() } // εϨου2 t1.join(); t2.join() println(s"counter: ${counter}") ———————————————————— counter: 200000000 Atomicม਺͸ɺΞτϛοΫʹ ΠϯΫϦϝϯτॲཧ͕Մೳ
  9. 26 Atomicม਺ private val uid = new AtomicLong(0L) @tailrec def

    getUniqueId(): Long = { val oldUid = uid.get val newUid = oldUid + 1 // uid͕oldUidͱ౳͚͠Ε͹ɺಉظతʹuidʹnewUidΛઃఆ͢Δ if(uid.compareAndSet(oldUid, newUid)) newUid // ࣦഊͨ͠৔߹͸ɺϦτϥΠ͢Δ else getUniqueId() } Atomicม਺ͷϝιου͸ϩοΫϑϦʔͳͷͰɺσουϩοΫ͕ى͖ͳ͍ ϩοΫΛͤͣʹɺଞͷεϨου͕ม਺Λมߋ͢Δͱɺ CAS(CompareAndSwap)͕ݕग़ʢ·ͨ͸ࣦഊʣ͠ɺͦΕͷૢ࡞Λ܁Γฦ͢͜ͱ͕Ͱ͖Δ
  10. 27 Atomicม਺Ϣʔεέʔε • ҆શੑͱ଱ো֐ੑͰධՁ͕ߴ͍ (CASϕʔεͷฒߦΞϧΰϦζϜ͸ϩοΫϑϦʔͱݺ͹ΕΔ) • ύϑΥʔϚϯεʹ͓͍ͯ͸ɺsynchronizedͱ΄ͱΜͲҧ͍͕ͳ͍ͱݴΘΕ͍ͯΔ • ෳ਺ͷม਺ͷߋ৽ʹ͸޲͍͍ͯͳ͍ ྫ

    ୯ҰͷΧ΢ϯλʔॲཧ Future಺෦Ͱ΋࢖ΘΕͯΔ object Future { def find[T](@deprecatedName('futurestravonce) futures: TraversableOnce[Future[T]]) (@deprecatedName('predicate) p: T => Boolean) (implicit executor: ExecutionContext): Future[Option[T]] = { …… val ref = new AtomicInteger(futuresBuffer.size) …… if (ref.decrementAndGet == 0) { ??? } …… } }
  11. 33 ΞΫλʔ͸಺෦ʹϛϡʔλϒϧͳঢ়ଶΛ࣋ͭ͜ͱ͕Ͱ͖ɺ ͦΕΛ҆શʹߋ৽͢Δ͜ͱ͕Ͱ͖Δ class GreetActor(val who: String) extends Actor {

    var greeting = "" def receive = { case `who` => greeting = s"hello, $who" case msg => sender ! msg } } ଞͷεϨου͔Βvarͷมߋ͸ผͷεϨου͔Βݟ͍͑ͯΔͱ͸ݶΒͳ͍ͷʹɺ ͳͥvarม਺ʹ@volatileએݴΛ͠ͳͯ͘΋େৎ෉ͳͷ͔ʁ ActorϞσϧ͸εϨουηʔϑ
  12. 37 Akka͕อূ͍ͯ͠Δϧʔϧ [Ҿ༻] https://doc.akka.io/docs/akka/2.4.7/general/jmm.html#Actors_and_the_Java_Memory_Model 1. The actor send rule ΞΫλʔ΁ͷϝοηʔδૹ৴͸ɺͦͷΞΫλʔ͕ͦͷϝοηʔδΛड৴͢Δલʹى͖Δ

    2. The actor subsequent processing rule ΞΫλʔͰͷ͋Δϝοηʔδͷॲཧ͸ɺͦͷΞΫλʔͰͷ࣍ͷϝοηʔδͷॲཧͷલʹى͜Δ ϝʔϧϘοΫεʹΑ࣮ͬͯݱ͍ͯ͠Δ