6

I have the following piece of code in a java application

Thread.currentThread().sleep(10000);

However eclipse is showing me the following warning:

The static method sleep(long) from the type Thread should be accessed in a static way

I am very proud of never release code with warnings, and I would like to get rid of this warning (it occurs in two different classes). Do I need to post the entire code?

Victor
  • 1,655
  • 9
  • 26
  • 38
  • Don't worry about releasing code with no warnings, worry about releasing code with as few bugs/weaknesses as possible, as that's the only reason the warnings are there in the first place. :D – Gordon Gustafson Oct 03 '11 at 22:24
  • @CrazyJugglerDrummer This warning should really be an error; it was a flaw to accept it as part of the language, IMOHO. –  Oct 03 '11 at 22:29
  • The message says that you should call the method in a static manner. So you fix the error by calling the method in a static manner. What is the problem, exactly? Are you not familiar with the distinction between static vs. non-static class data? If you aren't, then you really, really ought to make sure you are up on those kinds of basics before you attempt multi-threaded programs. Multi-threaded programs are hard to get right. – Karl Knechtel Oct 03 '11 at 22:40

5 Answers5

34

You call

Thread.sleep(10000);

It always makes the current thread sleep. Even if you did:

Thread t = new Thread(...);
t.start();
t.sleep(10000);

That would still make the current thread sleep for 10 seconds, while leaving the new thread to go on its merry way. This is almost the canonical example for why this warning is important - it's because you're calling a static method as if it were an instance method, which makes it look like it matters what you're calling it on. It doesn't. The value isn't even checked for nullity:

Thread t = null;
t.sleep(10000); // Still sleeps for 10 seconds...

(I'm proud to say I originally filed a feature request for this warning in Eclipse back in June 2002 :)

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 6
    ahahah Jon Skeet answered my question, there should be a badge for that! – Victor Oct 03 '11 at 22:25
  • 1
    @Victor: Nah, then everyone would get the badge! – Hovercraft Full Of Eels Oct 03 '11 at 22:27
  • *The value isn't even checked for nullity* -- which was considered a bug, it doesn't follow the JLS. I clearly remember when javac address the bug. Quote from *15.12.4.1 Compute Target Reference (If Necessary)*: ... *If the invocation mode is static, then there is no target reference. The expression FieldName is evaluated, but the result is then discarded*... firstly it used to check for nulls and threw NPE and then it was decided to be overly aggressive. – bestsss Oct 05 '11 at 00:16
  • 1
    @bestsss: Gosh, that's good to know, thanks - I hadn't realised that bit of behaviour was a bug. Frankly I think the whole thing is a design bug, but that's a different matter... – Jon Skeet Oct 05 '11 at 05:22
  • @Jon, I mean they considered it a bug but then... erm - no. I think they edited the spec with: *15.12.4.6 Example: Target Reference and Static Methods When a target reference is computed and then discarded because the invocation mode is static, the reference is not examined to see whether it is null* There are a few bugs related to this issue which caused some confusion. I, myself, used to access static fields (before `import static`) like that. – bestsss Oct 05 '11 at 07:55
4

Thread.sleep(...) (a static method on Thread).

Causes the currently executing thread to sleep ...

It doesn't make sense to tell another thread to sleep: making it static ensures this restriction (albeit "only with a warning").

The code in the post will compile because obj.sm is rewritten by the compiler to T.sm, where sm is a static method on class T and the compile-time type of obj is T: as such it is the static method which is invoked and not an instance method (for a particular Thread), which is what the warning is about.

Happy coding.

3

Yup, when you look at the doc for sleep() it says "static void sleep(long millis)". The "static" isn't there because of noise in the channel, it means that the method should be addressed Thread.sleep(...) instead of someThreadObject.sleep(...). As a "convenience" you can use the latter form, but it's strongly discouraged.

Hot Licks
  • 47,103
  • 17
  • 93
  • 151
  • yes but always calling via class sucks! It is much easier and dynamic to use an object. And alot of times doesnt matter. –  Apr 03 '20 at 21:37
2

The way to go is

Thread.sleep(10000);

With the intention, that you can send to sleep only yourself anyways. A real non-static method would imply, that you could send another thread sleeping too.

A.H.
  • 63,967
  • 15
  • 92
  • 126
2

Just call Thread.sleep(10000), it will cause the current thread to sleep. http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Thread.html#sleep(long)

Christopher Perry
  • 38,891
  • 43
  • 145
  • 187