【问题标题】:Thread management Mutex vs Synchronized线程管理互斥与同步
【发布时间】:2021-05-13 10:50:15
【问题描述】:

我有几个选择:

A

   GlobalScope.launch {
        countTo("A",5)
    }
    GlobalScope.launch {
        countTo("B",5)
    }

    
   private fun countTo(from:String, k: Int) {
        for (i in 0 until k) {
            RLog.d("From:$from: $i")
            Thread.sleep(1000)
        }
}

输出:

From:A: 0
From:B: 1
From:A: 1
From:B: 2
From:A: 2
From:B: 3
From:A: 3
From:B: 4
From:A: 4

B

   GlobalScope.launch {
        countTo("A",5)
    }
    GlobalScope.launch {
        countTo("B",5)
    }

   private val lock = Mutex()
   private suspend fun countTo(from:String, k: Int) {
    lock.withLock {
        for (i in 0 until k) {
            RLog.d("From:$from: $i")
            Thread.sleep(1000)
        }
    }

输出:

From:A: 0
From:A: 1
From:A: 2
From:A: 3
From:A: 4
From:B: 0
From:B: 1
From:B: 2
From:B: 3
From:B: 4

C

    GlobalScope.launch {
        countTo("A",5)
    }
    GlobalScope.launch {
        countTo("B",5)
    }

    @Synchronized
    private fun countTo(from:String, k: Int) {
        for (i in 0 until k) {
            RLog.d("From:$from: $i")
            Thread.sleep(1000)
        }
     }

输出:

From:A: 0
From:A: 1
From:A: 2
From:A: 3
From:A: 4
From:B: 0
From:B: 1
From:B: 2
From:B: 3
From:B: 4

D

    lifecycleScope.launch {
        countTo("A",5)
    }
    lifecycleScope.launch {
        countTo("B",5)
    }

    private fun countTo(from:String, k: Int) {
        for (i in 0 until k) {
            RLog.d("From:$from: $i")
            Thread.sleep(1000)
        }
    }

输出:

From:A: 0
From:A: 1
From:A: 2
From:A: 3
From:A: 4
From:B: 0
From:B: 1
From:B: 2
From:B: 3
From:B: 4

我的问题是:

  1. 是什么导致 A 和 D 的行为不同? GlobalScope 是否有更多线程而lifecycleScope 是否有单线程?
  2. B、C、D 的行为方式相同,但我对 Mutex 的假设是它阻止对线程的访问并且从不调用该函数。所以 synchronized 可以以同步的方式运行它。那么 mutex 与 synchronized 有何不同?
  3. lifecycleScope 在某些方面与同步的行为相同吗?

【问题讨论】:

    标签: android multithreading kotlin global-scope


    【解决方案1】:

    您的问题的答案是:-

    1. lifecycleScope.launch 不在单独的线程中运行代码,默认情况下它将使用Main Dispatcher,如果您希望它在单独的线程中运行,您可以传递像 lifecycleScope.launch(Dispatchers.IO) 这样的 Dispatcher,另一方面,GlobalScope 将通过默认使用 Dispatchers.Default 。您可以检查这一点,只需在 launch 中打印线程名称。

    2. 在这种情况下,Mutex@Synchronized 是相同的,因为您在整个执行过程中都持有 mutext,只有在线程完成运行其代码后才会释放它。 @Synchronized 将使方法本身成为 synchronized,其作用相同。

    3. lifecycleScope 只是一个作用域,与synchronized 无关。

    这些是对您的问题的叙述性较少的答案,我希望它是有意义的。您可以通过在 launch 内的 Log 中打印线程名称来检查这些行为。 请查看This nice answer 以获得更深入的了解。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-04
      • 2014-05-02
      • 1970-01-01
      • 1970-01-01
      • 2022-01-05
      • 2016-06-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多