Share
Embed
Transcript
38 slides
-
3 ϚϧνεϨουͷॏཁੑ ‣ ϜʔΞͷ๏ଇͷ่յ CPUΫϩοΫͷ಄ଧͪ ‣ ϚϧνίΞϓϩηοα࣌ͷ౸དྷ ฒߦ/ฒྻʹϓϩάϥϜΛ࣮ߦ͢Δඞཁ͕͋Δ ҰͭͷϓϩάϥϜͰෳͷεϨουΛ࣮ߦ͢Δ͜ͱ εϨου̍
ॲཧ εϨου2 ॲཧ εϨου3 ॲཧ ෳͷॲཧ͕ɺॱෆಉ͘͠ಉ࣌ʹى͜Γ͏Δ -
4 ϚϧνεϨουͷ͠͞ • ಡΈॻ͖ͷڝ߹ͷͨΊʹɺλΠϛϯάʹΑͬͯ݁Ռ͕ҟͳΔ߹͕͋Δ • σουϩοΫ ‣ εϨουؒͷಉظॲཧ/ഉଞ੍ޚ ‣ ࢥ͏Α͏ʹύϑΥʔϚϯε্͕͠ͳ͍͜ͱ
• ্ख͘ഉଞ੍ޚͰ͖ͳ͔ͬͨΓɺ༨ܭͳಉظॲཧ͕ΔͱٯʹύϑΥʔϚϯε͕Լ͕Δ -
5 ϚϧνεϨουؔ࿈༻ޠ ‣ ഉଞ੍ޚ ‣ εϨουηʔϑ ‣ ΞτϛοΫʢෆՄૢ࡞ʣ ෳͷτϥϯβΫγϣϯ͔Βಉ͡Ϧιʔεʹରͯ͠ɺ ಉ࣌ʹߋ৽ॲཧ͕ߦΘΕΔࡍʹɺσʔλͷ߹ੑΛอͭͨΊʹߦ͏ॲཧ
ϚϧνεϨουͰಈ࡞ͤͯ͞ͷͳ͍ϓϩάϥϜͷ͜ͱ(σουϩοΫɺσʔλڝ߹͕ى͖ͳ͍) ଞͷεϨουʹׂΓࠐΈΛͤͣ͞ɺݱࡏߦ͍ͬͯΔมߋૢ࡞͕࣮֬ʹऴΘͬͨޙʹ࣮ߦͰ͖Δ͜ͱ -
8 Volatileम০ࢠ 1.ίϯύΠϥͷ࠷దԽʢஔ͖͑ʣΛࢭ͢Δ 2.ίϯύΠϥͷ࠷దԽʢϦΦʔμʔʣΛࢭ͢Δ 3.volatileम০ࢠΛ༩͞ΕͨมɺϝΠϯϝϞϦʹอଘ͞Εɺ CPUΩϟογϡͷίϐʔͳͲ͕ى͖ͳ͍ @volatile var flag =
false // ϝΠϯϝϞϦʹอଘ͞ΕΔ [ৄ͍͠ࢿྉ] http://kannokanno.hatenablog.com/entry/20120528/1338229536 -
9 ϚϧνεϨουͷΈ εϨου1 ϝΠϯϝϞϦ εϨου2 ಡΈࠐΈ ಡΈࠐΈ ॻ͖ࠐΈ Ճࢉ •
࣮ߦޮΛ͋͛ΔͨΊʹɺ֤εϨου࡞ۀ༻ϝϞϦΛ͍࣋ͬͯΔ • جຊ࡞ۀ༻ϝϞϦʹରͯ͠ಡΈॻ͖͕ߦΘΕɺ దͳλΠϛϯάͰϝΠϯϝϞϦಉظ͢Δ ίϐʔ ಉظ ಉظ ίϐʔ -
11 Volatileम০ࢠ͕ղܾ͢Δ͜ͱ εϨου1 ϝΠϯϝϞϦ εϨου2 ಡΈࠐΈ ಡΈࠐΈ ॻ͖ࠐΈ ॻ͖ࠐΈ Ճࢉ
Ճࢉ Volatileम০ࢠʹΑͬͯϝΠϯϝϞϦʹ อଘ͢Δ͜ͱʹΑͬͯɺ͙ -
12 VolatileϢʔεέʔε ҎԼͷ݅Λຬͨ͢߹ʹ͑Δ 1.ͦͷมͷॻ͖ࠐΈ͕ɺͦͷมͷݱࡏͷʹґଘ͠ͳ͍ 2.ͦͷม͕ɺଞͷมͱͷෆมࣜʹΘΕ͍ͯͳ͍ ྫ 1 ͚ͩൃੜ͢ΔॏཁͳϥΠϑαΠΫϧɾΠϕϯτͷൃੜΛࣔ͢ɺεςʔλεϑϥά private[akka] abstract
class Mailbox(val messageQueue: MessageQueue) extends ForkJoinTask[Unit] with SystemMessageQueue with Runnable { @volatile var actor: ActorCell = _ … } Actor෦ͰΘΕ͍ͯΔ -
15 Synchronizedम০ࢠ Volatileम০ࢠʹͳ͍ϩοΫػߏΛ༻͍ͯɺ ΦϒδΣΫτϝιουʹରͯ͠ϩοΫΛஔ͢Δ͜ͱʹΑͬͯɺ ಉ࣌ʹෳͷεϨου͕ॲཧΛߦΘͳ͍Α͏ʹഉଞ੍ޚΛߦ͏ def process() = synchronized {
// ϝιουʹର͢Δഉଞ੍ޚ } def process() = obj.synchronized { // ΦϒδΣΫτʹର͢Δഉଞ੍ޚ } ͍͜ͳͤΕɺෳࡶͳॲཧ҆શʹߦ͑Δ -
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Λߋ৽͍ͯ͠Δ -
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Ϣʔεέʔε -
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() σουϩοΫ ͓ޓ͍͕ϩοΫΛղ์͞ΕΔͷΛͬͯ͠·͏ -
21 ϩοΫػߏͷ 1. ϩοΫՃࢉɾ݁߹Ͱ͖ͳ͍ 2. ϩοΫΛ͚ΕΔ 3. ϩοΫΛෆ༻ҙʹ͍͗ͯ͘͢ͳΔ 4. ؒҧͬͨϩοΫΛೖΕͯఆ֎ͷॲཧ͕ൃੜ͢Δ
5. ϩοΫͷஔͷॱংΛؒҧ͑Δ 6. Τϥʔͷൃݟ͕͍͠ɺΤϥʔ͔Βͷ෮ؼ͕ࠔ -
24 atomicύοέʔδ ୯Ұͷมʹର͢ΔϩοΫϑϦʔͰεϨουηʔϑͳϓϩάϥϛϯά Λαϙʔτ͢ΔΫϥεΛؚΉύοέʔδ • AtomicBoolean: BooleanܕΛѻ͏ • AtomicInteger: IntegerܕΛѻ͏
• AtomicLong: LongܕΛѻ͏ • AtomicReference<V>: ΦϒδΣΫτܕΛѻ͏ • … -
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มɺΞτϛοΫʹ ΠϯΫϦϝϯτॲཧ͕Մೳ -
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)͕ݕग़ʢ·ࣦͨഊʣ͠ɺͦΕͷૢ࡞Λ܁Γฦ͢͜ͱ͕Ͱ͖Δ -
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) { ??? } …… } } -
32 ActorϞσϧεϨουηʔϑ ΞΫλʔ෦ʹϛϡʔλϒϧͳঢ়ଶΛ࣋ͭ͜ͱ͕Ͱ͖ɺ ͦΕΛ҆શʹߋ৽͢Δ͜ͱ͕Ͱ͖Δ class GreetActor(val who: String) extends Actor
{ var greeting = "" def receive = { case `who` => greeting = s"hello, $who" case msg => sender ! msg } } -
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ϞσϧεϨουηʔϑ -
34 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 -
35 1. The actor send rule ΞΫλʔͷϝοηʔδૹ৴ɺ ͦͷΞΫλʔ͕ͦͷϝοηʔδΛड৴͢Δલʹى͖Δ “ΞϯόϯσουϝʔϧϘοΫεͷ߹ConcurrentLinkedQueueΛ͏͜ͱͰvolatile writeΛߦ͍ɺ
όϯσουϝʔϧϘοΫεͷ߹LinkedBlockingQueueΛ͏͜ͱͰϩοΫΛߦ͏” -
36 2. The actor subsequent processing rule ΞΫλʔͰͷ͋Δϝοηʔδͷॲཧɺ ͦͷΞΫλʔͰͷ࣍ͷϝοηʔδͷॲཧͷલʹى͜Δ “Ҏલͷϝοηʔδॲཧ࣌ʹߦͬͨॻ͖ࠐΈಉظ͞Εɺ
࣍ͷϝοηʔδΛॲཧ͢Δͱ͖ʹ؍ଌͰ͖Δ͜ͱ͕อূ͞ΕΔ” -
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 ΞΫλʔͰͷ͋ΔϝοηʔδͷॲཧɺͦͷΞΫλʔͰͷ࣍ͷϝοηʔδͷॲཧͷલʹى͜Δ ϝʔϧϘοΫεʹΑ࣮ͬͯݱ͍ͯ͠Δ -
38 ·ͱΊ • volatileએݴ͞ΕͨมɺৗʹϝϞϦ͔Β࠷৽ͷΛऔಘ͢Δ͕ɺ ΞτϛοΫͳԋࢉͰ͖ͳ͍ • synchronizedϓϩάϥϚ্͕खʹΘͳ͍ͱɺ σουϩοΫύϑΥʔϚϯεԼΛҾ͖ى͜͢ • ϚϧνεϨουڥͰͷ୯ҰมͷΞτϛοΫͳԋࢉ
concurrent.atomicύοέʔδʹؚ·ΕΔΦϒδΣΫτ͕ద͍ͯ͠Δ • ActorϞσϧϝʔϧϘοΫεʹΑͬͯεϨουηʔϑΛ࣮ݱ͍ͯ͠Δ