简体   繁体   中英

Passing a Runnable instance to Thread calls run() of Thread's subclass instead of run() of Runnable class

I have three classes as follows :

1.ThreadInstance

public class ThreadInstance extends Thread {
    public ThreadInstance() 
    {
    }
    public ThreadInstance(RunnableInstance r) {
        super(r);
    }
    public void run() {
        System.out.println("|Extend|");
    }
}

2.RunnableInstance

public class RunnableInstance implements Runnable {
    public void run() {
        System.out.println("|Implement|");
    }
}

3.Client

public class Client{
    public static void main(String[] args) {
        new ThreadInstance(new RunnableInstance()).start();
    }
}

OUTPUT prints |Extend| instead of |Implement|

In Client class, a thread is created by passing a runnable instance. So when this thread run, run() method of Runnable class(RunnableInstance) should be called. But in the above case, run() method of ThreadInstance is called.

I am not bale to get the reason behind this. Could anyone please put some light on what am i missing here. Also i checked the run() method of Thread class and found that if checks if runnable instance is not null, then it calls run() method from Runnable class.

i checked the run() method of Thread class and found that […] it calls run() method from Runnable class

You've overrided the run method so that your ThreadInstance no longer does this.

You need to pick one or the other. Either override run in Thread or pass it a Runnable . Not both.

Technically speaking , one could do the following:

public class ThreadInstance extends Thread {
    public ThreadInstance() {}
    public ThreadInstance(RunnableInstance r) { super(r); }

    public void run() {
        super.run(); // note
        System.out.println("|Extend|");
    }
}

But that is probably not a good idea unless you really know what you are doing. We generally shouldn't change the behavior of Thread .

See also:

From the Javadocs of Thread#start() :

Causes this thread to begin execution; the Java Virtual Machine calls the run method of this thread .

So when you call start() , the run method of ThreadInstance gets called.

Note that the default run method of class Thread calls run of the target Runnable class:

// this is the run method of the base Thread class
public void run() {
    if (target != null) {
        target.run();
    }
}

But since you override the run method in the subclass ThreadInstance , it no longer calls the target RunnableInstance .

You've overiden the run method of the thread class and you never call the super implementation, hence, the runnable never gets called.

You don't need to override the thread at all but if you must, you should, sometime, call super.run() within your run implementation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM