我知道Thread.sleep()
持有锁,但Object.wait()
释放锁。有人说yield
实际实现sleep(0)
。这是否意味着 yield 不会释放锁?
另一个问题。假设当前线程获得了锁,然后调用anotherThread.join()
. 当前线程是否释放锁?
我知道Thread.sleep()
持有锁,但Object.wait()
释放锁。有人说yield
实际实现sleep(0)
。这是否意味着 yield 不会释放锁?
另一个问题。假设当前线程获得了锁,然后调用anotherThread.join()
. 当前线程是否释放锁?
除非 javadoc 提到对象的监视器(例如Object.wait()
),否则您应该假设任何锁都将继续被持有。所以:
这是否意味着 yield 不会释放锁?
是的。
当前线程是否释放锁?
不。
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 的值。