【多线程与高并发(锁)】2、什么时候需要加锁

1、多线程操作共享变量可能导致的问题

首先,看下面的代码:

object LockDemo {

  var wordCount = 10

  def addWordCount(count: Int): Unit = {
    wordCount += count
  }

  def main(args: Array[String]): Unit = {

    val t1 = new Thread(() => {

      Thread.sleep(Duration.ofSeconds(1).toMillis)

      addWordCount(20)

    })


    val t2 = new Thread(() => {

      Thread.sleep(Duration.ofSeconds(1).toMillis)

      addWordCount(30)
    })

    t1.start()
    t2.start()

    Thread.sleep(Duration.ofSeconds(5).toMillis)

    println(wordCount)

  }
}

在上面的程序中,线程 t1和t2 在执行前都先sleep了一秒,此时两个线程读取到的 wordCount 的变量值都是 10,线程 t1 对这个变量+20,线程 t2 对这个变量 +30。我们最终看到的结果可能是 30 (10+20),也可能是 40(10+30)。但是这2个结果都不是我们想要的结果,我们需要的正确结果应该是 10+20+30=60。
在这种情况下,我们就需要加锁,可以把 addWordCount 方法锁住,当一个线程进入这个方法中时,不允许另外的线程对wordCount变量进行操作。

2、加锁的代码示例

下面是通过 synchronized 关键字加锁的代码示例

def addWordCount(count: Int): Unit = this.synchronized {
    wordCount += count
  }

再次执行1中的示例代码,发现每次运行的结果都是60

你可能感兴趣的:(多线程与高并发,Scala,锁)