kotlin - Kotlin 同步无法正常工作
问题描述
我正在尝试创建一个简单的程序,它是使用并发的布朗运动模型(杂质在单元格中随机左右移动)。我有杂质和细胞类。单元类包含单元数组,表示当前每个单元中有多少杂质。每个 Impurity 对象在自己的线程中更改 Cells 中的单元格数组。我正在启动线程,它们在无限循环中运行 1 秒。但在此之前和之后,我打印了单元格中的杂质总和,这些值不相等,这意味着我在同步方面做错了。这是代码:
细胞类:
object Cells {
var cell = Array(N) { 0 }
fun addImpurity(impurity: Impurity) {
cell[impurity.currentCell]++
}
@Synchronized
fun move(impurity: Impurity, direction: Direction) {
if (direction == Direction.LEFT && impurity.currentCell > 0) {
cell[impurity.currentCell]--
cell[impurity.currentCell - 1]++
impurity.currentCell--
} else if (direction == Direction.RIGHT && impurity.currentCell < N - 1) {
cell[impurity.currentCell]--
cell[impurity.currentCell + 1]++
impurity.currentCell++
}
Unit
}
fun printCells() {
for (c in cell)
print("$c ")
}
}
enum class Direction {
LEFT, RIGHT
}
杂质类:
class Impurity(var currentCell: Int) {
private lateinit var thread: Thread
init {
Cells.addImpurity(this)
}
fun startMoving() {
thread = Thread {
while (true) {
if (random() > P)
Cells.move(this, Direction.RIGHT)
else
Cells.move(this, Direction.LEFT)
}
}
thread.start()
}
fun stopMoving() = thread.interrupt()
}
和主要:
const val N = 10
const val K = 15
const val P = 0.5
fun main(args: Array<String>) {
val impurities = ArrayList<Impurity>()
for (i in 1..K)
impurities.add(Impurity(0))
println(Cells.cell.sum())
startMoving(impurities)
Thread.sleep(1000)
stopMoving(impurities)
Cells.printCells()
println(Cells.cell.sum())
}
private fun startMoving(impurities: ArrayList<Impurity>) {
for (impurity in impurities)
impurity.startMoving()
}
private fun stopMoving(impurities: ArrayList<Impurity>) {
for (impurity in impurities)
impurity.stopMoving()
}
提前致谢!
解决方案
我认为最好手动向线程发出信号,它应该通过让它包含一些它引用的标志来完成它的工作,以便知道何时退出循环。例如:
class Impurity(var currentCell: Int) {
...
private var _continue = true
fun startMoving() {
thread = Thread {
while (_continue) {
}
}
...
fun stopMoving() {
_continue = false
}
}
此外,您可能还想等到实际线程本身作为对stopMoving
. 这将确保所有线程在调用Cells.printCells
. 例如,您可以将此方法添加到Impurity
类中:
fun waitForEnded() = thread.join()
您可以stopMoving
在主类中更新以在向每个线程发出停止信号后调用此方法:
private fun stopMoving(impurities: ArrayList<Impurity>) {
for (impurity in impurities)
impurity.stopMoving()
impurities.forEach(Impurity::waitForEnded)
}
推荐阅读
- wix - WIX 不会卸载旧版本
- asp.net - 当应用程序的一层不依赖于另一层时,这意味着什么
- python - 如何使用 rasterio 设置 geotiff 的边界?
- python - 通过python将不同工作表中的数据从一个转移到另一个
- jbpm - JBPM 和 Java 12
- django - 如何在 EMR 集群上将 HUE 4.2 迁移到 HUE 4.4
- php - 如何检测从滚动条中选择的选项或在表单提交时在文本栏中输入值?
- java - 在哪里可以找到提取特定 exif 的元数据类型列表
- .net - Azure SQL 数据库应用程序
- regex - 用于在和文档中查找 R 的正则表达式