a. The Thread.join method is static b. The Thread.join method is always invoked on an instance of Thread c. The Thread.join method causes the current thread to wait for the referenced thread to die d. The Thread.join method declares an InterruptedException in the throws clause e. The Thread.join method accepts a timeout value as an argument f. The timeout value sets the minimum time that the current thread will wait for the death of the referenced thread g. Thread.join will return immediately if the timeout value is zero h. A timeout of zero will allow Thread.join to wait forever if necessary
Actually, the issue is that the meaning of the milliseconds argument is: If the value of the argument is 0, then wait forever (until the other thread dies.) If it is not zero, wait until the other thread dies, or until the timeout value is reached, whichever comes first. The semantics of the argument are arbitrary in that 0 means "wait as long as it takes."
All code in my posts, unless a source is explicitly mentioned, is my own.