JDK-8184719 : Implementation logic of wait(long timeout, int nanos) method in Object class is incorrect
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.lang
  • Affected Version: 8,9
  • Priority: P4
  • Status: Closed
  • Resolution: Not an Issue
  • OS: generic
  • CPU: generic
  • Submitted: 2017-07-12
  • Updated: 2017-08-09
  • Resolved: 2017-07-17
Related Reports
Relates :  
Description
FULL PRODUCT VERSION :
all version

ADDITIONAL OS VERSION INFORMATION :
All OS

A DESCRIPTION OF THE PROBLEM :
In wait method you are expecting time in milliseconds and nanoseconds. but in case user pass 0 milliseconds and 1 nano seconds , ideally system should wait maximum 1 nanoseconds but according to current implementation, It'll wait maximum 1000000 nanoseconds. 

REGRESSION.  Last worked in version 8u121

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Pass 0 as first parameter and 1 in second parameter. 

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Thread should wait maximum 1 nanoseconds but it'll wait max 1000000 nanoseconds. because inside wait method if nanoseconds b/w 0-999999 , you guys increasing  milliseconds 1, that's not correct.

 if (nanos > 0) {
            timeout++;
        }
ACTUAL -
Ideally system should wait max 1 nanoseconds.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
package org.vc.object;

public class WaitTest {

	public static void main(String[] args) {
		Message msg = new Message("process it");
		MyWait waiter = new MyWait(msg);
        new Thread(waiter,"vikas waiter").start();
        
        MyWait waiter1 = new MyWait(msg);
        new Thread(waiter1, "vikas waiter 1").start();
	}

}


class MyWait implements Runnable{
    
    private Message msg;
    
    public MyWait(Message m){
        this.msg=m;
    }

    @Override
    public void run() {
        String name = Thread.currentThread().getName();
        synchronized (msg) {
            try{
                System.out.println(name+" waiting to get notified at time:"+System.currentTimeMillis());
                msg.wait(0,1);
            }catch(InterruptedException e){
                e.printStackTrace();
            }
            System.out.println(name+" waiter thread got notified at time:"+System.currentTimeMillis());
            System.out.println(name+" processed: "+msg.getMsg());
        }
    }

}

class Message {
    private String msg;
    
    public Message(String str){
        this.msg=str;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String str) {
        this.msg=str;
    }

}
---------- END SOURCE ----------


Comments
Earlier concerns were that Object.wait returned too early and the discussion was thoroughly reviewed. http://mail.openjdk.java.net/pipermail/core-libs-dev/2014-November/029753.html
17-07-2017