3 回答
TA贡献1998条经验 获得超6个赞
你不能保证close()
之前发生 write()
。
你有volatile closed
各种各样的信号量。你可以用它来发出事件信号,但你不应该用它来保证互斥。在您的情况下,线程 A可以向线程 B发出信号(A 正在写入,B 从volatile
变量读取)但线程 A无法从线程 B接收信号,这会导致下面描述的问题情况。
volatile
仅保证读取将看到最近的写入,但不保证您的写入将在读取之前发生。
有问题的情况:
线程 B可能在线程 A翻转write()
并继续执行的过程中。closed = true
close()
通过保护整个执行来使用显式锁定write()
,并使用相同的锁来确保您close()
在写入时不会调用。
TA贡献1803条经验 获得超3个赞
基本上你在这里需要的是一个命令,即write
statement executed before close()
。
Volatile 无济于事,因为它只是将变量直接写入内存。
close()
它对声明没有任何规定同步关键字只是防止另一个线程进入另一个/同一个同步块,在同一个监视器上同步。如果两个任务都必须由不同的线程完成,则再次不适合订购。
在 Kotlin 中解决这个问题的一个非常简单的例子(java 将是类似的)。您创建一个可用于锁定的对象。
您的关闭线程
A
将等待获取 Object 的锁lock
另一个线程
B
不会等待获得锁。相反,它将关闭并通知所有线程完成它们的工作。A 现在可以进入临界区,
close()
并再次释放锁。
val lock = Object()
val A = Thread{
synchronized(lock) {
lock.wait()
closed = true; // closed is a volatile variable
close();
lock.notifyAll()
}
}
val B = Thread{
synchronized(lock) {
write()
lock.notifyAll()
}
}
t.start()
t1.start()
t.join()
t1.join()
请注意,此方法存在很大缺陷,是让您步入正轨的基本示例。您可能想要使用可重入锁,并在您的完整代码中仔细考虑。
添加回答
举报