Benjieming.Li
Benjieming.Li

Reputation: 143

What's the difference between different ways to start a thread?

I have a class named MyThread which extends the Thread class and implement the run() function.When I want to run it , I got two ways:

  1. new a instance and call the function,like: new MyThread().start()
  2. new a instance and transmit the instance to the construction function of Thread as a parameter and then call the start function of Thread. Like this: (new Thread(new MyThread)).start();

Anybody can just tell the difference?

Upvotes: 14

Views: 2132

Answers (8)

Sage
Sage

Reputation: 15418

Thread itself is an implementation of Runnable. When create an instance of Thread and start it, it will executes it's own run() method. If non-null Runnable target is given to it's constructor, then it will invoke it's target's run() method as is evident from the implemented run() method of Thread class:

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

The two ways to create a new thread of execution:

  1. First one is to declare a class(i.e. PThread) to be a subclass of Thread: PThread extends PThread and should override the run method of class Thread. We can then easily create instantiate of this class and invoke start() on it:

    PThread pThread = new PThread(args);
    pThread.start(); 
    
  2. Second one is to declare a class that implements the Runnable interface: RThread implements Runnable then implements the run method. We will have to instantiate the RThread and pass it to a Thread instance as a Runnable target:

     RunThread rThread = new RunThread(args); // args constructor argument if required 
     Thread t = new Thread(rThread);
     t.start();
    

As you have seen from the above way to start a thread, It is actually allowed a class extending a Thread, such as PThread to be passed to a new Thread constructor as a Runnable target to start it. Because Thread itself is an implementation of Runnable.

   PThread pThread = new PThread(args);
   Thread t = new Thread(pThread);  
         // allowed as pThread is extending Thread and hence, 
         //an implementation of Runnable 
   t.start();

But this operation is unnecessary or, rather you should not do it. As pThread is already a Thread, we could just call pThread.start() to executes it's run() method, which is the heart of a Thread. Creating another thread just to execute pThread is just extra overhead as it will not do anything other than executing pThread's run() method.

However, you should not actually use an extension of Thread at all. Because,

implementing Runnable is always preferable over extending a Thread:

  • Inheriting all Thread methods are additional overhead just for representing a Task which can can be done easily with Runnable.

  • Implementing Runnable to a Class still allows us to extend it to other class if necessary.

  • In OOP, extending a class generally means adding new functionality, modifying or improving behaviors. If we are not making any modification on Thread or changing it's behavior, than use Runnable interface instead.

  • Runnable interface represent a Task which can be executed by either plain Thread or Executors or any other means. so logical separation of Task as Runnable than Thread is good design decision.

  • Executors, which makes life easier with multi-threading accepts Runnable as task.

Reference:

  1. Class Thread
  2. Difference between Thread class and Runnable interface

Upvotes: 1

T.J. Crowder
T.J. Crowder

Reputation: 1074355

Because you've said your class extends Thread, the second one is a bit redundant. In your second example, you're not using your class as a Thread, you're just using it as a Runnable.

Normally, you'd either extend Thread and then call its own start (your #1), or you'd implement Runnable and then use a Thread to run it (your #2). But you wouldn't extend Thread and then use another Thread to run it.

In terms of what's different, if you need to do anything to control or interrogate the thread, in your first case you'd use the Thread methods on the instance of your class; in the second case, you'd use them on the instance you create with new Thread. If you extend Thread but run it via #2, the Thread methods on your instance are irrelevant and could be confusing.

That last bit is probably clearer with examples:

Example of extending Thread:

class Foo extends Thread {
    public void run() {
        // ...
    }
}

// Create it
Foo foo = new Foo();

// Start it
foo.start();

// Wait for it to finish (for example)
foo.join();

Note we started and joined the thread via the foo reference.

Example of implementing Runnable:

class Foo implements Runnable {
    public void run() {
        // ...
    }
}

// Create it
Foo foo = new Foo();

// Create a Thread to run it
Thread thread = new Thread(foo);

// Start it
thread.start();

// Wait for it to finish (for example)
thread.join();

Note we started and joined the thread via the thread reference.

Don't do this:

class Foo extends Thread {
    public void run() {
        // ...
    }
}

// Create it
Foo foo = new Foo();

// Create a Thread to run it -- DON'T do this
Thread thread = new Thread(foo);

// Start it
thread.start();

...because now you have Thread#join available on both foo and thread; which is the right one to use? (The answer is: The one on thread, but it's confusing, so it's best not to do that.)

Upvotes: 19

wuchang
wuchang

Reputation: 3069

Well, you have two method to implement a multi-thread.

  1. extend Thread and use new MyThreand().start() to start your thread.

  2. implement Runnable interface. In this condition, you can use (new Thread(new MyThread)).start(); to start a thread.

For detailed infomation, just refer to oracle official doc.

Upvotes: 4

Stefan Winkler
Stefan Winkler

Reputation: 3956

If your class itself extends Thread you can follow your first way:

MyThread myThread = new MyThread();
myThread.start();

If you look into the JavaDoc, you'll see that your second way is targeted towards classes that (just) implement Runnable (which means that your class just needs to implement run() method).

public class MyClass implements Runnable {
     public void run() { ... }
}

Thread thread = new Thread(new MyClass());
thread.start();

The difference is that Runnable is only an interface whereas Thread is a class. This means that if you want to have your logic as part of a class which needs for some reason to extend a different class, then you can still implement Runnable and use the second way.

Upvotes: 1

anish
anish

Reputation: 7412

There are absolutely no difference between how you start the Thread (class implementing Runnable or extending Thread class)

It's only the abstraction that you apply, note (Runnable object, is more general, because the Runnable object can subclass a class other than Thread) Good Coding Practice.

In both of the cases Thread.start() will called

Upvotes: 0

Aaron Digulla
Aaron Digulla

Reputation: 328614

You shouldn't do this. Creating a thread does change some variables like the "number of unstarted threads" in ThreadGroup.

While it shouldn't exactly cause problems, it's bad style and will confuse people ("Why did he do that? There must be a good reason!").

Upvotes: 1

MichaelMoser
MichaelMoser

Reputation: 3500

(new Thread(new MyThread)).start();

each Thread implements Runnable; in this case MyThread instance is used as Runnable the new thread calls the run method implemented by MyThread. You will not be able to stop the thread ( or control it by any means) by using MyThread.

Upvotes: 0

Narendra Pathai
Narendra Pathai

Reputation: 41945

The MyThread instance you are passing is just acting as Runnable and not as a separate Thread.

There is basically no difference logically in both ways:

What Thread internally does on start() is, calls the run() method of Runnable.

And when you are doing new Thread(new MyThread()).start(), you are just being redundant as Thread itself implements Runnable.

But it will make no difference logically as the run() method of MyThread will be called by the new Thread.

Upvotes: 1

Related Questions