LoginSignup
1
0

More than 1 year has passed since last update.

Scalaの勉強はじめました 13 〜スレッドセーフ〜

Last updated at Posted at 2022-05-04

はじめに

N予備校でScalaの「並行処理プログラミング」を受講しています。

メモリの可視性

複数のスレッドで共有している状態の変数への変更は、変更したスレッドからは見えるが、もう一方のスレッドからはその変更が見えない。
「可視性がない」状態。

yield

他の実行可能なスレッドがある場合は実行する、ない場合は待つ。

object MemoryVisibility extends App {
  var number = 0
  var ready = false

  new Thread(() => {
    while (!ready) {
      Thread.`yield`()
    }
    println(number)
  }).start()

  number = 2525
  ready = true
}

同期が取れていないので、実行環境によって結果はまちまち。
readynumberの変更が別スレッドから感知できないため。

volatile アノテーション

@volatileがついた変数は、Javaのコンパイラとランタイムにおいて、
複数のスレッドから共有される変数と認識される。

@volatile var number = 0
@volatile var ready = false

アトミックな処理を求める同期化が必要な場合には使えないので、
その場合はsynchronizedブロックを使うこと。

逸出

逸出とは、本来の公開すべきではないフィールドのオブジェクトや変数が公開されてしまうこと。

varや可変オブジェクトを利用しないのが一つの手段。
変数の宣言はprivate[this] valなどで行う。

スレッド拘束

データが必ず 1 つのスレッドからしかアクセスされないようにする
特定のスタックからインスタンスの参照が漏れることの無いようにする方法

並列コレクション

java.util.concurrentの利用。
synchronizedブロックなどの処理をAPIとして提供する並行コレクション。

ConcurrentHashMap
ハッシュマップをスレッドセーフにした部品。
並行処理で更新などをしても パフォーマンスが出る。

CopyOnWriteArrayList
ArrayListはスレッドセーフでないために、並行処理を行う場合に利用する。
SeqSetを使う場合がほとんど。

BlockingQueue
分散処理システムを実装できる並行処理部品。
メインスレッドが仕事をキューに入れて、ワーカースレッドが仕事のキューを消化していく。

シンクロナイザ

スレッドの制御フローを扱える部品のこと

  • ラッチ
    最終ステートに到着するまでせき止めておくゲートの働きをする部品
  • FutureTask
    計算結果が取得可能な Runnable 途中でキャンセルする機能も
  • セマフォ
    Semaphore 何かのリソースにアクセスさせる際、その数を制限したい時に用いる並行処理部品
  • バリア
    他のスレッドが全員揃ったらスタートできるといういう並行部品

まとめ

並行処理はコード見ただけでは結果がすぐにわからない。
それぞれ違いは実際使ってみて理解していくしかないかなと思います。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0