new Runnable() but no new thread?
Asked Answered
C

8

21

I'm trying to understand the code here , specifically the anonymous class

private Runnable mUpdateTimeTask = new Runnable() {
public void run() {
   final long start = mStartTime;
   long millis = SystemClock.uptimeMillis() - start;
   int seconds = (int) (millis / 1000);
   int minutes = seconds / 60;
   seconds     = seconds % 60;

   if (seconds < 10) {
       mTimeLabel.setText("" + minutes + ":0" + seconds);
   } else {
       mTimeLabel.setText("" + minutes + ":" + seconds);            
   }

   mHandler.postAtTime(this,
           start + (((minutes * 60) + seconds + 1) * 1000));
   }
};

The article says

The Handler runs the update code as a part of your main thread, avoiding the overhead of a second thread..

Shouldn't creating a new Runnable class make a new second thread? What is the purpose of the Runnable class here apart from being able to pass a Runnable class to postAtTime?

Thanks

Collusion answered 27/1, 2012 at 6:36 Comment(1)
No. Runnables are not Threads. docs.oracle.com/javase/tutorial/essential/concurrency/…Gimbals
A
51

Runnable is often used to provide the code that a thread should run, but Runnable itself has nothing to do with threads. It's just an object with a run() method.

In Android, the Handler class can be used to ask the framework to run some code later on the same thread, rather than on a different one. Runnable is used to provide the code that should run later.

Analogue answered 27/1, 2012 at 6:41 Comment(4)
"Runnable itself has nothing to do with threads" this is conceptually WRONG! Please read documentation. Runnable interface should be implemented by any class whose instances are intended to be executed by a thread. It is also confusing when Runnable is passed, but stuff happens in the same thread. Please read about "principle of least surprise".Irreducible
@glaz666, the Runnable documentation talks about threads because they're the most common use of Runnable, but the interface is suitable for any kind of callback. I think the Android Handler's use of Runnable is entirely reasonable — it's better than defining a new Android-specific interface that's identical to Runnable but with a different name.Analogue
An example of "new Runnable()" without "extends Thread" nor "implements Runnable": docs.oracle.com/javase/tutorial/uiswing/examples/start/…Pullover
@glaz666, I've never liked the wording in Runnable's javadoc (that you quoted earlier), and apparently the Java folks agreed that it was too narrow. Notice how they improved the same wording in Callable's javadoc: "The Callable interface is similar to Runnable, in that both are designed for classes whose instances are potentially executed by another thread."Abbeyabbi
R
27

If you want to create a new Thread...you can do something like this...

Thread t = new Thread(new Runnable() { public void run() { 
  // your code goes here... 
}});
Rightist answered 27/1, 2012 at 6:44 Comment(1)
Not what the OP asked.Annihilation
N
17

The Runnable interface is another way in which you can implement multi-threading other than extending the Thread class due to the fact that Java allows you to extend only one class.

You can however, use the new Thread(Runnable runnable) constructor, something like this:

private Thread thread = new Thread(new Runnable() {
public void run() {
   final long start = mStartTime;
   long millis = SystemClock.uptimeMillis() - start;
   int seconds = (int) (millis / 1000);
   int minutes = seconds / 60;
   seconds     = seconds % 60;

   if (seconds < 10) {
       mTimeLabel.setText("" + minutes + ":0" + seconds);
   } else {
       mTimeLabel.setText("" + minutes + ":" + seconds);            
   }

   mHandler.postAtTime(this,
           start + (((minutes * 60) + seconds + 1) * 1000));
   }
});

thread.start();
Nowicki answered 27/1, 2012 at 6:44 Comment(2)
so does this example create a new thread or not, because you have used Thread but not called start()..Collusion
@shishirgarg: This example creates a new Thread object. To execute it, simply call the start() method like so: thread.start(). That should internally call the run() method (note, you should never call the run() method yourself) which kick starts the thread.Nowicki
I
10

You can create a thread just like this:

 Thread thread = new Thread(new Runnable() {
                    public void run() {

                       }
                    });
                thread.start();

Also, you can use Runnable, Asyntask, Timer, TimerTaks and AlarmManager to excecute Threads.

Incredible answered 8/7, 2014 at 20:57 Comment(3)
you can override the run() method of Thread. What's the benefit of creating the Runnable too?Korwin
@RoundSparrowhilltx: multiple inheritance in Java is possible only with interfaces. And Runnable, unlike Thread, is an interface. So you can spam a run method in any class that needs to be/have its own thread (and declare it to implement Runnable) w/o messing up your extends hierarchy.Wimer
@RoundSparrowhilltx: Also with Java 8 you can create a Runnable with a lambda expression (because Runnable has single method!) which cuts down cruft a bit. codejava.net/java-core/the-java-language/…Wimer
R
7

Runnable is just an interface, which provides the method run. Threads are implementations and use Runnable to call the method run().

Rogation answered 27/1, 2012 at 6:42 Comment(0)
O
3

Shouldn't creating a new Runnable class make a new second thread?

No. new Runnable does not create second Thread.

What is the purpose of the Runnable class here apart from being able to pass a Runnable class to postAtTime?

Runnable is posted to Handler. This task runs in the thread, which is associated with Handler.

If Handler is associated with UI Thread, Runnable runs in UI Thread.

If Handler is associated with other HandlerThread, Runnable runs in HandlerThread


To explicitly associate Handler to your MainThread ( UI Thread), write below code.

Handler  mHandler = new Handler(Looper.getMainLooper();

If you write is as below, it uses HandlerThread Looper.

HandlerThread handlerThread = new HandlerThread("HandlerThread");
handlerThread.start();
Handler requestHandler = new Handler(handlerThread.getLooper());

Onrush answered 4/10, 2017 at 9:48 Comment(0)
C
0

Best and easy way is just pass argument and create instance and call thread method

Call thread using create a thread object and send a runnable class object with parameter or without parameter and start method of thread object.

In my condition I am sending parameter and I will use in run method.

new Thread(new FCMThreadController("2", null, "3", "1")).start();

OR

new Thread(new FCMThreadController()).start();

public class FCMThreadController implements Runnable {
private String type;
private List<UserDeviceModel> devices;
private String message;
private String id;


    public FCMThreadController(String type, List<UserDeviceModel> devices, String message, String id) {

        this.type = type;
        this.devices = devices;
        this.message = message;
        this.id = id;
    }



    public FCMThreadController( ) {

    }

    @Override
    public void run() {
        // TODO Auto-generated method stub

    }



}
Charmeuse answered 17/12, 2016 at 14:14 Comment(0)
N
0

A thread is something like some branch. Multi-branched means when there are at least two branches. If the branches are reduced, then the minimum remains one. This one is although like the branches removed, but in general we do not consider it branch.

Similarly when there are at least two threads we call it multi-threaded program. If the threads are reduced, the minimum remains one. Hello program is a single threaded program, but no one needs to know multi-threading to write or run it.

In simple words when a program is not said to be having threads, it means that the program is not a multi-threaded program, more over in true sense it is a single threaded program, in which YOU CAN put your code as if it is multi-threaded.

Below a useless code is given, but it will suffice to do away with your some confusions about Runnable. It will print "Hello World".

class NamedRunnable implements Runnable {

    public void run() { // The run method prints a message to standard output.
        System.out.println("Hello World");
    }

    public static void main(String[]arg){ 
        NamedRunnable namedRunnable = new NamedRunnable( );
        namedRunnable.run();
    } 
}
Necessitous answered 24/6, 2017 at 14:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.