RFR 8034168: ThreadMXBean/Locks.java failed, blocked on wrong object

Jaroslav Bachorik jaroslav.bachorik at oracle.com
Thu Feb 20 06:16:55 PST 2014


This was discussed when reviewing 
ThreadMXBean/SynchronizationStatistics.java

Regarding a busy wait checking the thread states and issuing 
Thread.yield() now and then David Holmes wrote:
"Not elegant and not completely reliable either. Probably adequate on a
multi-core system but single-core and with some schedulers it could 
just be a busy spin." [1]

As far as I understand, the only benefit of using Thread.yield() instead 
of Thread.sleep() would be 10-100ms shorter execution time, right?

-JB-

[1] http://mail.openjdk.java.net/pipermail/jmx-dev/2013-October/000484.html

On 19.2.2014 17:56, Martin Buchholz wrote:
> The jsr166 tck tests make systematic use of Thread.yield, e.g.
>
>
>      /**
>       * Spin-waits up to the specified number of milliseconds for the given
>       * thread to enter a wait state: BLOCKED, WAITING, or TIMED_WAITING.
>       */
>      void waitForThreadToEnterWaitState(Thread thread, long timeoutMillis) {
>          long startTime = System.nanoTime();
>          for (;;) {
>              Thread.State s = thread.getState();
>              if (s == Thread.State.BLOCKED ||
>                  s == Thread.State.WAITING ||
>                  s == Thread.State.TIMED_WAITING)
>                  return;
>              else if (s == Thread.State.TERMINATED)
>                  fail("Unexpected thread termination");
>              else if (millisElapsedSince(startTime) > timeoutMillis) {
>                  threadAssertTrue(thread.isAlive());
>                  return;
>              }
>              Thread.yield();
>          }
>      }
>
>
>
> On Tue, Feb 18, 2014 at 11:29 PM, Jaroslav Bachorik <
> jaroslav.bachorik at oracle.com> wrote:
>
>> On 18.2.2014 18:06, Martin Buchholz wrote:
>>
>>> Not checking any details, but tests that want to wait for a particular
>>> thread state are a good reason to use
>>>
>>> volatile boolean flag;
>>> ...
>>> while (!flag) Thread.yield();
>>>
>>> I prefer calling Thread.yield to sleeping in this special case, in part
>>> because I don't want to rely on the implementation of sleep, while yield
>>> is
>>> semantically a no-op.  (Also sleeping 100ms is a long time for a computer)
>>>
>>
>> There were discussions for a similar fix regarding Thread.yield(). The
>> concern was that using Thread.yield() in a tight loop might very easily
>> lead to starvation on single core machines. Therefore Thread.sleep(10) is
>> used to be sure the flag setting thread has actually a chance to progress.
>>
>> -JB-
>>
>>
>>
>>>
>>>
>>> On Tue, Feb 18, 2014 at 8:22 AM, Jaroslav Bachorik <
>>> jaroslav.bachorik at oracle.com> wrote:
>>>
>>>   Please, review the following test change.
>>>>
>>>> Issue : https://bugs.openjdk.java.net/browse/JDK-8034168
>>>> Webrev: http://cr.openjdk.java.net/~jbachorik/8034168/webrev.00
>>>>
>>>> The test fails because of falsely evaluating the thread being parked as
>>>> actually waiting on a monitor. This is because there is no difference in
>>>> java thread state for those two situations. The test is using Phaser for
>>>> synchronization between the checked and checking thread to make sure an
>>>> appropriate code section is entered before performing asserts. Then it
>>>> checks the checked thread state and waits till it becomes WAITING.
>>>> Unfortunately, when Phaser needs to wait it parks the thread and sets the
>>>> thread state to WAITING. From now on the test is in a completely random
>>>> state and the result will largely depend on timing - thus failing
>>>> intermittently.
>>>>
>>>> The solution is to use an additional volatile variable to prevent falsely
>>>> indicating the park() induced WAITING state.
>>>>
>>>> Thanks,
>>>>
>>>> -JB-
>>>>
>>>>
>>>
>>
>



More information about the serviceability-dev mailing list