首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么线程在保存锁时而不是在获取锁之前测试条件/属性?

为什么线程在保存锁时而不是在获取锁之前测试条件/属性?
EN

Stack Overflow用户
提问于 2017-10-08 23:59:40
回答 2查看 52关注 0票数 2

来自于Herlihy的多处理编程艺术:

假设一个线程想要等待直到某个属性被保存。线程在保存锁时测试属性。如果属性不保存,则线程调用等待()释放锁并休眠,直到被另一个线程唤醒为止。 1条件条件= mutex.newCondition();2.3 mutex.lock() 4尝试{5,而(!属性){ //不高兴6 condition.await();//等待属性7}condition.await (InterruptedException e) {8. //依赖于应用程序的响应9} 10 . //快乐:属性必须持有11 } 图8.2如何使用条件对象。

为什么线程在测试属性之前调用mutex.lock() (如果属性不保持,则线程调用await())而不是之后?

谢谢。

EN

回答 2

Stack Overflow用户

发布于 2017-10-09 00:23:42

如果您将此更改为:

代码语言:javascript
运行
复制
while (!property) {
   mutex.lock();
   condition.await();
   mutex.unlock();

最大的问题是如果属性的值在行之间发生变化。

代码语言:javascript
运行
复制
while (!property) {

还有这条线

代码语言:javascript
运行
复制
   mutex.lock();

然后,当该属性已处于过载状态时,您将等待其更改。

如果假设您只能在保持互斥锁的同时更改属性,那么对于问题中的示例,您不能调用

代码语言:javascript
运行
复制
   condition.await();

当属性处于过路状态时。

为了详细说明这一假设,问题中的示例代码通常会与设置属性值的某种方式并驾齐驱。这可能是沿着…

代码语言:javascript
运行
复制
void setProperty(boolean newproperty) {
    mutex.lock();
    property = newproperty;
    condition.signalAll();
    mutex.unlock();
}

没有这第二部分,你永远无法保证你只打电话给他。

代码语言:javascript
运行
复制
condition.await();

而财产是假的。

票数 1
EN

Stack Overflow用户

发布于 2017-10-09 01:21:52

获取锁的一件事是创建一个内存屏障,这样就不会使用可能已经过时的缓存值来检查条件。

另外,获取锁确保检查的值不会被其他线程并发更改。否则,线程可以测试条件并继续获取锁,然后在获得锁时查找更改的条件。无论如何,线程都需要检查所持有的锁。

线程想要确定锁定对象的状态,然后修改该状态,同时确保该状态不会由于另一个线程的干扰而从状态下改变。这意味着它必须保持锁跨越检查和行动。线程在不成功的检查后等待(释放锁直到发出信号),然后在下一次检查之前获得锁。一旦检查成功,那么它就会保持锁,直到它能够完成对锁定对象的操作。

只有当检查成功时(例如添加到有界缓冲区),对锁定对象执行的操作才有意义。或者,该操作可能涉及多个更改,其中所有更改都需要一起应用(如果锁定对象的数据结构不是为并发访问(如ArrayList )设计的,则该数据结构需要采取多个步骤来添加元素,并且干扰会破坏数据结构)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46637217

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档