Best way of creating and using an anonymous Runnable class
Asked Answered
D

11

43

I want to use an anonymous class for Runnable. There are two ways, but I don't know if they do the same thing or not:

Method one: using Runnable directly and then calling run():

new Runnable() {
    @Override
    public void run() {
    }
}.run();

Method two: create an anonymous Runnable and paste to Thread, using the start() method instead of run():

new Thread(new Runnable() {
    @Override
    public void run() {
    }
}).start();

I think method two is obviously true. But, I don't know if it does the same thing as method one. Can we call the run() method on a Runnable directly?

Drugget answered 7/10, 2012 at 18:21 Comment(0)
T
28

No, you usually won't call run() directly on a Runnable as you will get no background threading that way. If you don't want and need a background thread, then fine call run() directly, but otherwise if you want to create a background thread and run your Runnable from within it, you must create a new Thread and then pass in the Runnable into its constructor, and call start().

Also, there are other ways of accomplishing this task including use of Executors and ExecutorServices, and you should look into the uses of this as they offer more flexibility and power than using a bare bones Thread object.

Also you'll want to have a look at use of the Future interface and the FutureTasks class that are like Runnables only they allow you to return a result when complete. If you've used a SwingWorker, then you've already used a Future interface without realizing it.

Tailspin answered 7/10, 2012 at 18:22 Comment(0)
L
29

As the others have mentioned, using the Thread class is the correct way. However, you should also look in to using Javas Executors framework to handle running threads.

Executors.newSingleThreadExecutor().execute(new Runnable() {
    @Override 
    public void run() {
        // code in here
    }
});

Of course, just using Thread directly is fine. But it is generally advised (or preferred) to use the framework. Let Java handle the fine details for you.

Lollapalooza answered 7/10, 2012 at 18:38 Comment(0)
T
28

No, you usually won't call run() directly on a Runnable as you will get no background threading that way. If you don't want and need a background thread, then fine call run() directly, but otherwise if you want to create a background thread and run your Runnable from within it, you must create a new Thread and then pass in the Runnable into its constructor, and call start().

Also, there are other ways of accomplishing this task including use of Executors and ExecutorServices, and you should look into the uses of this as they offer more flexibility and power than using a bare bones Thread object.

Also you'll want to have a look at use of the Future interface and the FutureTasks class that are like Runnables only they allow you to return a result when complete. If you've used a SwingWorker, then you've already used a Future interface without realizing it.

Tailspin answered 7/10, 2012 at 18:22 Comment(0)
A
7

Initialization of Runnable could be done via lambda expression:

Runnable myRunnable = () -> {
    //code you want to execute
};

Calling myRunnable.run() directly will execute the code on the same thread. If it should run async, you'll need to wrap it inside a thread by calling new Thread(myRunnable).start() or inline the lambda:

new Thread(() -> {
    //code you want to execute
}).start();
Acrosstheboard answered 28/9, 2020 at 19:37 Comment(1)
Nice. This is supported started from Java 8 and up.Algie
A
6

The Runnable interface must be executed inside a Thread. If you want to find another way to wrap inline, a chunk of code inside a Thread, try:

Thread t = new Thread()
{
     public void run()
     {
        // put whatever code you want to run inside the thread here.
     }
};

t.start();
Apogamy answered 7/10, 2012 at 18:29 Comment(0)
C
4

I would like to add something on this discussion (you already got good answers).
If your Runnable object is stateless, in order to reduce memory allocations (which take time + consume some memory - think about a case an application vastly uses threads) - please consider having the a static field holding the runnable object.

private static Runnable runnable = new Runnable() { //Once again - do this only if this is a statelss object!
   public void run() {
   }
} 

//Use the runnable somewhere in the code
Clamper answered 7/10, 2012 at 19:42 Comment(0)
C
3

Always remember that Runnable is just a code that you want or is able to run in a Thread. One way to define Runnable code anonymously is:

  Runnable codeToRunOnThread=new Runnable() {
      @Override
      public void run() {
      //code to run in a thread you want
      }
  };

And then you can create a thread and pass the Runnable you created to that new Thread like this

  Thread myThread=new Thread(codeToRunOnThread);
  myThread.start();

After calling the start() method of the Thread class, the code that goes inside the run() method runs on the newly created thread.

You can also look different way of creating Runnable object here

Censurable answered 30/10, 2017 at 14:23 Comment(0)
E
2

In method one it will just work like a method as Runnable interface implementing and calling it,but there will be no background thread created. The fact is when we call start method it causes the corrosponding thread to begin execution, the Java Virtual Machine calls the run method of this thread internally . So to start a thread we need to call start method with interface Runnable refernce . In method one even we can't call start method with Runnable interface reference as Runnable interface does not support start() method .So its mandatory to create the object of Thread class to start thread execution .

Extortioner answered 14/6, 2017 at 18:33 Comment(0)
S
1

The first way is wrong : it doesn't create a new thread so it's useless.

It's just like putting the code outside of a runnable.

Note that there are two ways of launching a new thread on code defined in an anonymous class, as described in Thread's javadoc but your method 1 isn't among them and your method 2 is the one you should usually prefer.

Suppliant answered 7/10, 2012 at 18:22 Comment(0)
S
1

As @Hovercraft mentionds, if you call a Runnable.run() method directly, a Thread is not created at all. It's just like calling any other method (System.out.println(...), ...).

When you pass a Runnable object to the Thread constructor, that sets the target field in the Thread to be your object:

this.target = target;

Then when you call start() on the Thread, this does the work of forking the new thread and calling the Thread.run() method. The Thread.run() calls the target's run() method in turn:

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

So passing the Runnable to a Thread and then calling start() is the way to run your Runnable in the background in a separate thread.

Sealer answered 7/10, 2012 at 18:27 Comment(0)
B
0

Your method 1 usually can not do any useful work. With this method if you want to get the output of simple HelloWorld.java program i.e. "Hello World", it will resemble the following useless code, but it prints "Hello World". So you should use your Second Method. Useless code:

class MyRunnable implements Runnable {

    public void run() { 
    System.out.println("Hello World");
    }

    public static void main(String[]arg){ 
    MyRunnable myRunnable = new NamedRunnable( );
    namedRunnable.run();
    } 
}
Brew answered 24/6, 2017 at 15:47 Comment(0)
T
0

Here is a simple code example of how to create an anonymous Runnable class properly and handle memory leak (Example for Android):

public class MainActivity extends Activity{
@Override
protected void onCreate(Bundle savedInstanceState) {

            MyRunnable myRunnable = new MyRunnable(this);
            myHandler.postDelayed(myRunnable, TimeUnits);
}

// Must be declared as a static class    
private static class MyRunnable implements Runnable {
        WeakReference<MainActivity> mActivity;
        // Creating weakreference
        MyRunnable(MainActivity activity) {
            mActivity = new WeakReference<>(activity);
        }

        @Override
        public void run() {
            MainActivity activity = mActivity.get();
            // Checking reference exist or not
            if (activity != null) {
                    //Do necessary tasks
                }
            }
        }
    }

}
Thereafter answered 31/1, 2018 at 11:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.