4

Most of the time I want to run a block of code in a new thread where it does some time consuming stuff but in some circumstances I want to run it with the thread that called a method. Is it bad practice to directly call the run method?

If it is not a good idea is it best to put the code in another method which can be called by the new thread or duplicate the code?

This is some example code, it is just to illustrate what I want to achieve:

class Main {
    public Main() {
        new Thread(new WorkerThread(1, 2)).start(); // This is what I'd do if I wanted it to run in a new thread.
        new WorkerThread(1, 2).run(); // Is it bad practice to do this?
    }
}

class WorkerThread implements Runnable {
    private int int1, int2;

    public WorkerThread(int int1, int int2) {
        this.int1 = int1;
        this.int2 = int2;
    }

    public void run() {
        // Do something time consuming with the ints.
    }
}
user2248702
  • 2,741
  • 7
  • 41
  • 69
  • 3
    It's perfectly fine to call `run`. But you shouldn't use the name `WorkerThread` for a class that isn't a `Thread`. – Dawood ibn Kareem Apr 28 '14 at 06:17
  • If you call direct run method then it will be treaded as main thread.It will run fine but it will not be multithreading, no new thread will be created – Kick Apr 28 '14 at 06:22

6 Answers6

4

Calling run executes the code synchronously; whereas run method would allow the code to execute asynchronously.

Calling run directly is often times beneficial in a testing scenarios where threading needs to be avoided.

Suren Raju
  • 3,012
  • 6
  • 26
  • 48
4

I know there's already a lot of other answers, but your question is about "practice", and that word does not appear in any of them.

What is good practice is to write code that is easy for other people to understand and preferably, easy for them to understand without any in-line comments.

There is nothing wrong with calling foobar.run() as long as the meaning of "run" is obvious to somebody reading your program.

Your class is named WorkerThread even though it is not a thread. That might confuse people. And calling workerThread.run() might confuse them even more as to whether or not a thread actually is involved.

I would say, go ahead and call the run() method if that makes sense, but change the class so that readers know that you are not trying to start a thread and doing it the wrong way.

Farvardin
  • 5,336
  • 5
  • 33
  • 54
Solomon Slow
  • 25,130
  • 5
  • 37
  • 57
3

You can call run method directly, but that will execute in your current thread. No extra threads will be created. Calling "start" however will create a new thread and internally call the run method.

So if you are looking for thread creation, you need to use start method.

More details here

Community
  • 1
  • 1
Hirak
  • 3,601
  • 1
  • 22
  • 33
3

a good idea is to use Extract Method (Refactoring technique) to extract parts (may be all) of your run method that need to be run directly.

class Worker implements Runnable {
    private int int1, int2;

    public Worker(int int1, int int2) {
        this.int1 = int1;
        this.int2 = int2;
    }

    public void work() {
        ...
    } 

    public void run() {
        work();
    }
}

then

new Thread(new WorkerThread(1, 2)).start(); 
new WorkerThread(1, 2).work(); // Looks good!
Farvardin
  • 5,336
  • 5
  • 33
  • 54
  • What is the use of new WorkerThread(1, 2).work(); ?? It will not create any new Thread. – Kick Apr 28 '14 at 06:31
  • Yes, already read the question.You are putting work() method in run method and calling directly. – Kick Apr 28 '14 at 06:40
  • he want to use a functionality in two case : 1-running a thread, 2.directly so i extract that functionality from `run()` (that is basically responsible for running thread) and named it `work()`. so when u look at `Worker` class u can see a piece of code that may be run without creating a thread... – Farvardin Apr 28 '14 at 06:46
2

In the now outdated Java Blackberry API, implementations of Runnable are used for a variety of things, for instance definition of GUI callbacks. The interface Runnable can be seen as an object-oriented way of defining function pointers, so Runnable and multithreading are orthogonal concepts in the first place.

Codor
  • 17,447
  • 9
  • 29
  • 56
1

There is nothing wrong with calling the run() method of a Runnable directly.

In Java 1.4 and some early versions of 1.5 (admittedly due to a bug), there can be problems if you create a Thread but don't go on to call its start() method, because resources are allocated and never released.

See Why is my Java program leaking memory when I call run() on a Thread object?

Your code avoids this - the object you call run() on is not a Thread. If you had done this:

 class WorkerThread extends Thread {
      public void run() { ... }
 }

 ...

 public void main() {
       WorkerThread a = new WorkerThread();
       WorkerThread b = new WorkerThread();
       a.start // runs parallel to main thread
       b.run(); // runs in main thread
 }

... then in buggy JVMs the resources allocated to b would not get cleared up.

It's not obvious that you should let JVM bugs (on versions you probably are not targeting) influence your coding style. However here it's clear that the code is mis-stating its intent. We don't intend to run this code in a separate thread, so we shouldn't declare it as a thread. The introduction of the new Thread(Runnable x) style (which you have used) makes it easy to only create Threads if you intend them to actually be threads.

My only suggestion for your code is to change the name of WorkerThread -- since it is not always a thread. Worker would be a fine generic name. In real code you'd give it a name that indicates what kind of work it does!

new Thread(new Worker(1, 2)).start();
new Worker(1, 2).run(); 

As has been noted already - there are uses for a Runnable other than wrapping in a Thread. The two concepts are not tightly coupled.

Community
  • 1
  • 1
slim
  • 40,215
  • 13
  • 94
  • 127