gpt4 book ai didi

java - @Synchronized 方法中的 Kotlin IllegalMonitorStateException

转载 作者:行者123 更新时间:2023-12-02 05:42:06 28 4
gpt4 key购买 nike

我正在尝试用 Kotlin 重现一个老式的解决方案,以解决具有多线程和共享内存空间的经典消费者-生产者问题。在Java中,我会使用同步方法来访问共享空间。然而,在 Kotlin 中,@Synchronized 注解的方法似乎抛出 IllegalMonitorStateException。我本以为带注释的方法的行为应该与 Java 中的行为完全相同,但事实似乎并非如此。我使用 synchronized(){} 函数解决了问题,但我仍然对 @Synchronized 不起作用感到困惑。 这是为什么?

在下面的代码中,生产者通过增加 SynchronizedBox 内的计数器(长整型)来“生成”一个新值,而消费者读取该值,然后将其打印到控制台。

Kotlin MessageBox 无法工作

package concurrency.producer_consumer

class MessageBox(var message: Long = 0): SynchronizedBox {
private val lock = Object()
private var empty = true

@Synchronized
override fun syncIncrement() {
while (!empty) {
lock.wait()
}

message++
empty = false
lock.notifyAll()
}

@Synchronized
override fun readValue(): Long {
while (empty) {
lock.wait()
}

val readValue = message
empty = true
lock.notifyAll()

return readValue
}
}

有效的 Java 变体:

package concurrency.producer_consumer;

public class JBox implements SynchronizedBox {
private long value = 0;
private boolean empty = true;

@Override
public synchronized void syncIncrement() {
while (!empty) {
try {
wait();
} catch (InterruptedException e) {
}
}

value++;
empty = false;
notifyAll();
}

@Override
public synchronized long readValue() {
while (empty) {
try {
wait();
} catch (InterruptedException e) {}
}

empty = true;
return value;
}
}

实际运行的 Kotlin 版本:

package concurrency.producer_consumer

class MessageBox(var message: Long = 0): SynchronizedBox {
private val lock = Object()
private var empty = true

override fun syncIncrement() {
synchronized(lock) {
while (!empty) {
lock.wait()
}

message++
empty = false
lock.notifyAll()
}
}

override fun readValue(): Long {
synchronized(lock) {
while (empty) {
lock.wait()
}

empty = true
lock.notifyAll()
return message
}
}
}

其余代码:

消费者: 包 concurrency. Producer_consumer

class Consumer(private val messageBox: SynchronizedBox): Runnable {

override fun run() {
println("consumer thread: ${Thread.currentThread().id}: started")

while (true) {
println("consumer: ${messageBox.readValue()}")
Thread.sleep(1_000)
}
}
}

制作人:

class Producer(private val messageBox: SynchronizedBox): Runnable {

override fun run() {
println("producer thread: ${Thread.currentThread().id}: started")

while (true) {
messageBox.syncIncrement()
Thread.sleep(1_000)
}
}
}

界面

package concurrency.producer_consumer

interface SynchronizedBox {
fun syncIncrement()
fun readValue(): Long
}

启动器

package concurrency.producer_consumer

fun main() {
val box: SynchronizedBox = MessageBox()
val producer1 = Producer(box)
val consumer = Consumer(box)

val threadP1 = Thread(producer1)
val threadC = Thread(consumer)

threadP1.start()
threadC.start()
}

最佳答案

看起来确实 @Synchronized 锁定了 MessageBox 并且它不起作用只是因为在 Kotlin 中所有东西都扩展了 Any 而不是 Java 的 对象。尽管不推荐在 Kotlin 中进行并发编程,但解决方案是简单地扩展 Object,如下所示 MessageBoxLock:

package concurrency.producer_consumer.message_box

@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN")
class MessageBoxLock(var message: Long = 0): Object(), SynchronizedBox {

private var empty = true

@Synchronized
override fun syncIncrement() {
while (!empty) {
wait()
}

message++
empty = false
notifyAll()
}

@Synchronized
override fun readValue(): Long {

while (empty) {
wait()
}

empty = true
notifyAll()

return message
}
}

关于java - @Synchronized 方法中的 Kotlin IllegalMonitorStateException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56127895/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com