5

可能重复:
如果在同步方法中调用 thread.yield() 是否会失去对象锁定?

我知道Thread.sleep()持有锁,但Object.wait()释放锁。有人说yield实际实现sleep(0)。这是否意味着 yield 不会释放锁?

另一个问题。假设当前线程获得了锁,然后调用anotherThread.join(). 当前线程是否释放锁?

4

2 回答 2

4

除非 javadoc 提到对象的监视器(例如Object.wait()),否则您应该假设任何锁都将继续被持有。所以:

这是否意味着 yield 不会释放锁?

是的。

当前线程是否释放锁?

不。

于 2012-04-16T14:39:47.263 回答
1

sleep将线程置于等待状态,yield将线程直接返回到就绪池。(因此,如果一个线程让步,它可以直接从运行到就绪池,然后再次被调度程序选中,而无需等待。)两者都与锁定无关。

来自Java 语言规范

Thread.sleep 使当前正在执行的线程在指定的持续时间内休眠(暂时停止执行),具体取决于系统计时器和调度程序的精度和准确性。线程不会失去任何监视器的所有权,并且恢复执行将取决于调度和执行线程的处理器的可用性。

重要的是要注意 Thread.sleep 和 Thread.yield 都没有任何同步语义。特别是,编译器不必在调用 Thread.sleep 或 Thread.yield 之前将缓存在寄存器中的写入刷新到共享内存,编译器也不必在调用 Thread.sleep 或 Thread 之后重新加载缓存在寄存器中的值。屈服。

例如,在以下(损坏的)代码片段中,假设 this.done 是一个非易失性布尔字段:

while (!this.done)
     Thread.sleep(1000);

编译器可以自由地读取 this.done 字段一次,并在每次执行循环时重用缓存的值。这意味着循环永远不会终止,即使另一个线程更改了 this.done 的值。

于 2012-08-07T12:45:54.910 回答