Наиболее часто используемая и простая в использовании технология параллельного программирования в 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/…Посмотреть другие статьи блоггеров