Параллельное программирование на Scala: мониторинг и синхронизация

Большие данные

Наиболее часто используемая и простая в использовании технология параллельного программирования в Java — это ключевое слово synchronized, и путь параллельного программирования в Scala также может начаться с synchronized. За синхронизацией на самом деле стоит технология монитора.

Что такое монитор

Монитор — это распространенная технология для решения задач параллельного программирования, которая может эффективно решить две распространенные проблемы взаимного исключения и синхронизации, обычно переводимые как «монитор» или «монитор». Лично я думаю, что «монитор» может лучше выразить значение слова «монитор», которое относится к управлению общими переменными и процессу работы с общими переменными, чтобы они поддерживали параллелизм.

Scala синхронизируется

Synchronized — это реализация монитора в Java, которую можно использовать для блоков кода или методов, так что только один поток может получить к нему доступ в каждый момент времени, реализуя взаимное исключение потоков. Когда поток получает блокировку, другие потоки будут ждать в очереди, чтобы добиться синхронизации потоков.

Scala расширяет это ключевое слово, но синтаксис отличается.

//用于代码块
obj.synchronized {
    ...
}
//用于方法
def func(): Unit = this.synchronized {
    ...
}

Как и в Java, здесь это можно опустить, потому что это заблокированный объект по умолчанию, но опускать его не рекомендуется.

Экземпляр Scala

import java.util.concurrent.TimeUnit

object SynchronizedDemo {

  private var inc: Int = 0

  def addOne(): Unit = this.synchronized {
    TimeUnit.SECONDS.sleep(1)
    inc += 1
  }

  def main(args: Array[String]): Unit = {
    for (i <- 1 to 10) {
      new Thread {
        override def run(): Unit = {
          println(s"run thread with object method $i")
          addOne()
        }
      }.start()
    }
    val instance = new SynchronizedDemo
    for (i <- 1 to 10) {
      new Thread {
        override def run(): Unit = {
          println(s"run thread with class method $i")
          instance.addOne()
        }
      }.start()
    }
    while (true) {
      println(s"object inc=$inc, class inc=${instance.inc}")
      TimeUnit.SECONDS.sleep(1)
    }
  }


}

class SynchronizedDemo {
  private var inc: Int = 0

  def addOne(): Unit = this.synchronized {
    TimeUnit.SECONDS.sleep(1)
    inc += 1
  }
}

вывод программы

run thread with class method 7
run thread with class method 4
run thread with object method 8
run thread with object method 7
run thread with class method 10
run thread with class method 8
run thread with class method 9
run thread with object method 5
run thread with object method 3
run thread with object method 2
run thread with object method 4
run thread with object method 10
run thread with object method 9
run thread with class method 5
run thread with class method 3
object inc=0, class inc=0
run thread with object method 1
run thread with class method 6
run thread with class method 1
run thread with class method 2
run thread with object method 6
object inc=1, class inc=1
object inc=2, class inc=2
object inc=3, class inc=2
object inc=4, class inc=4
object inc=5, class inc=5
object inc=6, class inc=6
object inc=7, class inc=7
object inc=8, class inc=8
object inc=9, class inc=9
object inc=10, class inc=10

Разобрать

  • Переменная inc и метод addOne определены как в объекте SynchronizedDemo, так и в классе SynchronizedDemo Функция метода addOne заключается в добавлении 1 к inc.
  • В основном методе создается 10 потоков для вызова метода addOne, а inc увеличивается на 1 10 раз.
  • Поскольку переменная inc не является потокобезопасной, добавление ключевого слова synchronized в метод addOne делает операцию модификации потокобезопасной. Это гарантирует, что inc увеличится с 1 до 10.
  • Это в объекте и классе не одно и то же.This в объекте указывает на объект объекта с именем SynchronizedDemo, а объект в классе является экземпляром объекта класса. (В Scala нет статических классов и статических методов, объект SynchronizedDemo фактически создает одноэлементный объект с именем SynchronizedDemo)

Если addOne, определенный в классе, изменить на следующее:

  def addOne(): Unit = SynchronizedDemo.synchronized {
    TimeUnit.SECONDS.sleep(1)
    inc += 1
  }

Методы addOne, определенные в двух местах, будут взаимоисключающими, и вывод будет выглядеть следующим образом:

run thread with object method 2
run thread with object method 1
run thread with object method 3
run thread with object method 4
run thread with object method 5
run thread with object method 6
run thread with object method 7
run thread with object method 8
run thread with object method 9
run thread with object method 10
run thread with class method 1
run thread with class method 2
run thread with class method 3
run thread with class method 4
run thread with class method 5
run thread with class method 6
run thread with class method 7
run thread with class method 8
run thread with class method 9
run thread with class method 10
object inc=0, class inc=0
object inc=1, class inc=0
object inc=1, class inc=1
object inc=1, class inc=2
object inc=1, class inc=3
object inc=1, class inc=4
object inc=1, class inc=5
object inc=1, class inc=6
object inc=1, class inc=7
object inc=1, class inc=8
object inc=1, class inc=9
object inc=1, class inc=10
object inc=2, class inc=10
object inc=3, class inc=10
object inc=4, class inc=10
object inc=5, class inc=10
object inc=6, class inc=10
object inc=7, class inc=10
object inc=8, class inc=10
object inc=9, class inc=10
object inc=10, class inc=10

Код этой статьи

Репозиторий на гитхабе

При перепечатке просьба указывать первоначальный адрес:Liam-blog.beautiful/2019/07/14/…Посмотреть другие статьи блоггеров