Why doesn't java.lang.Thread call the run () method of its explicit java.lang.Runnable at startup?

Java docs claim that if we set a Runnable target when creating a new thread, the .start() that thread would run the run() method of the supplied runnable.

If so, should this test code not print "a" (instead of printing "b")?

 public class test { public static void main(String[] args) { Runnable r = new Runnable() { @Override public void run() { System.out.println("a"); } }; Thread t = new Thread(r) { @Override public void run() { System.out.println("b"); } }; t.start(); } } 
+6
source share
8 answers

Because you are overriding the Thread.run () method.

Here is the implementation of Thread.run () :

 @Override public void run() { if (target != null) { target.run(); } } 

to try:

 }) { @Override public void run() { super.run(); // ADD THIS LINE System.out.println("b"); } }.start(); 

You will get ab .

+16
source

The default implementation is a Runnable call. However, you override the default implementation and DO NOT call runnable. The easiest way to fix this is

  new Thread(new Runnable() { @Override public void run() { System.out.println("a"); } }) { @Override public void run() { super.run(); // call the default implementation. System.out.println("b"); } }.start(); 
+9
source

The default implementation of Thread.run () does what javadocs say (see source)

 public void run() { if (target != null) { target.run(); } } 

However, Thread.run () is publicly available and you redirect it, so it calls your println ("b") and completely ignores the Runnable passed in the constructor. Maybe Thread.run () should be final, but it is not.

+3
source

In fact, you extend the Thread class and call start on an instance of this anonymous subclass.

I think the confusion is that the “Java Doc” refers to the java.lang.Thread class not for your class that extends this class.

eg.

 Runnable r = new Runnable() { @Override public void run() { System.out.println("a"); } }; Thread t = new Thread(r); 

Now, if he does not call it run , then java doc is wrong. This is not true.

+1
source

You have redefined the default implementation of Thread.run() in what I think is an anonymous subclass, hence what JavaDoc says is no longer applicable.

If you try

 public class Test { public static void main(String[] args) { new Thread(new Runnable() { @Override public void run() { System.out.println("a"); } }) .start(); } } 

You will receive the answer you expect a .

+1
source

The first block overrides run in Runnable . The second block overrides run in Thread . When you call start on Thread , its run method is called. By default, the run method in Thread calls the Runnable.run method, but since you overloaded Thread.run , there is no code to run Runnable to run Runnable - only your code to print. A.

+1
source

The documentation in which I says the following: “Causes this thread to start, the Java virtual machine calls the execution method of that thread. ” This means that you should print b instead of a , since you redefined the run() Thread method.

+1
source

You call the start () method. Reading the documents in the link you specify indicates:

public void start () Forces this thread to start execution; The Java Virtual Machine calls the method to start this thread.

You must call the run () method if you want to call the Runnable object run method.

public void run () If this thread was created using a separate Runnable run object, then the Runnable object run method is started; otherwise, this method does nothing and returns.

+1
source

Source: https://habr.com/ru/post/904402/


All Articles