考虑以下代码:
Thread A:
closed = true; // closed is a volatile variable
close();
Thread B:
while(true){
if(!closed){
write();
}
else {
...
}
}
如果我理解正确,closed = true;
发生在close();
之前,而closed = true;
发生在write();
之前,但是{ {1}}和close();
。
以上代码是否确保write();
仅在write();
之前被调用?如果没有,可以进行哪些修改以使其起作用?还是我必须使用close()
?
答案 0 :(得分:1)
您已经提供了答案:“还是我必须使用同步?”是的!
答案 1 :(得分:1)
基本上,这里需要的是一个顺序,即write
之前执行的close()
语句。
close()
语句没有任何内容在Kotlin中解决该问题的非常简单的示例(java将是类似的)。您创建一个可用于锁定的对象。
A
将等待获取对对象lock
的锁定B
不会等待获取锁。相反,它将关闭并通知所有线程执行其工作。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()
请注意,此方法存在很大缺陷,是使您步入正轨的基本示例。您可能要使用可重入锁,并仔细阅读完整代码。
答案 2 :(得分:1)
您不能保证// webpack config
plugins: [
new CopyWebpackPlugin([
{
from: resolvePath('static'),
to: resolvePath(isCordova ? 'cordova/www/static' : 'www/static'),
},
]),
new CleanWebpackPlugin()
]
发生在 close()
之前。
您有write()
作为各种信号量。您可以使用它来表示事件,但不要使用它来保证相互排斥。在您的情况下,线程A 可以向线程B 发出信号(A正在写入,B从volatile closed
变量中读取),但是线程A 无法收到来自线程B 的信号,该信号导致出现如下所述的问题情况。
volatile
仅保证读取的内容可以看到最新的写入内容,但不保证您的写入内容发生在读取之前。
线程B 可能位于volatile
的中间,而线程A 翻转write()
并继续执行closed = true
。 / p>
通过保护close()
的整个执行来使用显式锁定,并使用相同的锁定来确保在编写过程中不调用write()
。
您可以通过根据Mangat的答案同步同一对象或使用SDK中的 ReadWriteLock 来做到这一点。