Search code examples
javamultithreadingrunnable

Local field with Thread type in Runnable


Is it a kind of bad design to use local Thread field in Runnable implemented class like this:

    public class TestingThread implements Runnable {
        Thread t;   

        public TestingThread() {
            t = new Thread(this, "Testing thread");

        }
        public void start()
        {
            t.start();
        }
...

Solution

  • Although this kind of question is obviously opinionated, I will tell you why I think that this is a design flaw. (Actually, I provoked this question, so maybe I should answer.)

    A Runnable is an object holding the code that will (or should) be executed within a thread. The documentation explains it this way:

    The Runnable interface should be implemented by any class whose instances are intended to be executed by a thread.

    The main idea behind the Runnable interface is to separate the executable code from the means of executing it. There are several possibilities of running such code in an own thread.

    One of those possibilities is the Thread class. From its documentation:

    There are two ways to create a new thread of execution. One is to declare a class to be a subclass of Thread. This subclass should override the run method of class Thread. An instance of the subclass can then be allocated and started. [...] The other way to create a thread is to declare a class that implements the Runnable interface. That class then implements the run method. An instance of the class can then be allocated, passed as an argument when creating Thread, and started.

    In my opinion, you always should do the latter. Define implementations of the Runnable interface, pass instances of them to the constructor of a Thread, then start the thread. Example:

    class MyRunnable implements Runnable { ... }
    
    void runMyCodeInOwnThread() {
        Runnable runnable = new MyRunnable();
        Thread thread = new Thread(runnable);
        thread.start();
    }
    

    The other way of executing a Runnable in a thread is an Executor, although you most likely will use an ExecutorService (actually a subtype of Executor). The utility class Executors will most likely be used for retrieving an executor service. Example:

    class MyRunnable implements Runnable { ... }
    
    void runMyCodeInOwnThread() {
        Runnable runnable = new MyRunnable();
        ExecutorService executor = Executors.newSingleThreadExecutor();
        Future<?> future = executor.submit(runnable); // or simply "executor.execut(runnable);"
    }
    

    If you don't tangle your runnable with the means of how to execute it, you are free to use either mechanism or change it in the future when requirements advance.

    However, as I looked through the classes' documentations, I also saw the same mechanism in the examples. Still, I think this is not a good design.