Kotlin 中如何在线程之间传输数据

问题描述 投票:0回答:1

我必须编写一段代码,创建两个线程 - S 和 W。线程 S 以 1000 毫秒的延迟执行从 true 到 false 的切换。线程 W 正在等待线程 S 的“true”,并以 100ms 的延迟从 30 秒开始倒计时输出到控制台,并在线程 S 切换回 false 时暂停其操作。 线程运行终止的条件是倒计时达到 0 秒。

首先,我创建了两个类 - ThreadW 和 ThreadS。 在 ThreadS 中,我创建了 true 和 false 之间的状态切换

ThreadS.kt

class ThreadS() : Thread() {
    override fun run()
    {
        var isTrue:Boolean = true
        while (true)
        {
            if (isTrue)
            {
                Thread.sleep(1000)
                isTrue = false
                println(isTrue)
            }
            else
            {
                Thread.sleep(1000)
                isTrue = true
                println(isTrue)
            }
        }
    }
}

在主文件中,我创建了协程并创建了 ThreadS 的类实例,然后启动它

import kotlinx.coroutines.*
import kotlinx.coroutines.channels.*

fun main() = runBlocking {
    var t2 = ThreadW()
    t2.start()
}

问题是我必须将切换器的值转移到另一个线程,并且不知道如何正确执行。 我曾试图通过渠道解决这个问题,但我的尝试没有成功。 这是 ThreadW 文件的代码,我尝试通过渠道解决它

import kotlinx.coroutines.*
import kotlinx.coroutines.channels.*

class ThreadW() : Thread() {
    override fun run() {
        val a = runBlocking {
            var timer : Int = 30
            var t1 = ThreadS()
            val channel = Channel<Boolean>()
            launch { t1.start() }
            val dataFromChannel = channel.receive()
            println(dataFromChannel)
            println("Done")
            if (dataFromChannel == true)
            {
                Thread.sleep(100)
                timer -= 1
            }
            println(timer)
        }
    }
}
multithreading kotlin kotlin-coroutines data-transfer
1个回答
0
投票

在我看来,

isTrue
timer
变量应该在两个线程之间共享并存在于它们之外。您应该解决的经典问题是可能的竞争条件,当一个线程更新变量而另一个线程同时读取该值时,会导致获得stale值。

有多种方法可以防止竞争情况。在这种情况下,使用

Atomic
似乎是最简单的解决方案。

val isTrue = AtomicBoolean(true)
val timer = AtomicInteger(30)

原子类型保证每次读/写操作都发生在单条指令中,并且不会与中间的值发生交互。

fun main() {
    val isTrue = AtomicBoolean(true)
    val timer = AtomicInteger(30)

    val threadW = thread {
        while (timer.get() != 0) {
            println("ThreadW runs")
            if (isTrue.get()) {
                println("Timer: $timer")
                Thread.sleep(100L)
                timer.getAndDecrement()
            }
        }
    }

    val threadS = thread {
        while (timer.get() != 0) {
            println("ThreadS runs")
            if (isTrue.get()) {
                println("isTrue = true. Sleeping...")
                Thread.sleep(1000L)
                isTrue.set(false)
                println("Set to false")
            } else {
                println("isTrue = false. Sleeping...")
                Thread.sleep(1000L)
                isTrue.set(true)
                println("Set to true")
            }
        }
    }
}

您也可以使用协程来完成此操作,只需将

thread
替换为
launch()
:

fun main() {
    val isTrue = AtomicBoolean(true)
    val timer = AtomicInteger(30)
   
    val threadW = launch(Dispatchers.Default) {
        while (timer.get() != 0) {
            println("ThreadW runs")
            if (isTrue.get()) {
                println("Timer: $timer")
                delay(100L) // Note that instead of Thread.sleep() coroutines use delay()
                timer.getAndDecrement()
            }
        }
    }
   
    val threadS = launch(Dispatchers.Default) {
        ...
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.