Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bad practice to use Runnable as callback / subroutine?

Is it's considered bad practice to use Runnable as a callback?

Considering that Runnable is meant to be used with threads (see it's JavaDoc), I'm wondering if this is okay - or whether I should make my own interface for this purpose.

What I'm talking about is something like:

public class KeyBinding {
    public KeyBinding(KeyStroke stroke, Runnable handler) {
        //...
    }
}
like image 324
MightyPork Avatar asked Mar 28 '14 21:03

MightyPork


People also ask

Which is better implementing runnable or extending thread?

In the second approach, while implementing Runnable interface we can extends any other class. Hence we are able to use the benefits of Inheritance. Because of the above reasons, implementing Runnable interface approach is recommended than extending Thread class.

Can we extend thread and implement runnable at the same time?

You should almost never do that. The type Thread already implements Runnable . The only reason to do this is if you want to be explicit in your source code. There is only one way to create a thread: creating a Thread instance and invoking its start() method.

Can runnable throw exception?

What happens when Runnable encounters an exception ? Runnable can't throw checked exception but RuntimeException can be thrown from the run(). Uncaught exceptions are handled by the exception handler of the thread, if JVM can't handle or catch exceptions, it prints the stack trace and terminates the flow.

Which of the following is the correct usage of runnable interface?

The runnable interface is used to write applications which can run in a separate thread. Any class that implements the runnable interface is called a thread. The code of the thread is executed by the interpreter after the thread is started.


2 Answers

Don't use Runnable as a callback; it might cause confusion: people and code quality tools sometimes expect it to be used with threads only.

I did myself use Runnable as a callback — I thought it seemed fairly well suited for use as a generic callback. A month later someone found my code snipped:

doneCallback.run();

and he noticed that the doneCallback was a Runnable, and that invoking .run() directly resulted in a warning in our code quality analysis program (Sonar). So, to fix the warning?, or because he thought the intention was to create a thread?, he forked a new thread, and called run() via that thread instead.

However, forking a thread there, broke stuff.

To avoid confusion, now I'm instead creating a generic callback interface that's not related to threads in any way. I'm just adding a class Callback with a method call. I think I'd better not use java.util.concurrent.Callback because that one is related to threads too.

like image 149
KajMagnus Avatar answered Oct 21 '22 00:10

KajMagnus


Actually, Runnables can be used for any purpose.

"The general contract of the method run is that it may take any action whatsoever"(Runnable javadoc)

Generally, it should not be bad practice, definitely better practice than creating an extra unnecessary interface in your own code.

like image 35
k_g Avatar answered Oct 21 '22 00:10

k_g