Reputation: 1567
In Android we have Handler#post(Runnable) method to post some code to the main thread from another
Is it possible to make same thing in plain java (for instance while using swing)?
Explaining the question: Assume we have two threads: ThreadA and ThreadB. Both are started already and running side-by-side. And ThreadB wants ThreadA to invoke some method (again, ThreadA is already running).
Addition optional question (you may not answer it): And if it's possible, someone explain me how does exactly Handler do in Android. How it's able to post some code to MainThread? What is a purpose of the Looper?
Upvotes: 3
Views: 2571
Reputation: 2063
Addressing your additional question:
You said "In Android we have Handler#post(Runnable) method to post some code to the main thread from another"
It is not exactly correct. You can 'post some code' from any thread A to any thread B provided that thread B is initialized as a Looper
and the thread A has a reference to a Handler
for the target thread B.
It is very convenient when you need to do something on the UI thread because the UI thread already has a Looper
and you can retrieve it from nearly everywhere. The static method Looper.getMainLooper
is a way to get a Looper
for the main thread. If you initialize a Handler
with this Looper
you can post a Runnable
or send a Message
to it (though if you post Runnable
it also gets wrapped into a Message
) and it will be executed on the UI thread.
Looper
, as the name hints, is basically running a non-terminating loop for a thread. The Looper
has an associated MessageQueue
which it constantly checks for new Messages.
Via the Handler
initialized with a Looper
you can enqueue Messages
on this thread. The Messages
are processed in a sequential order, depending on the when
field of a Message
.
Here's a basic implementation of a Looper thread:
class LooperThread extends Thread {
public Handler mHandler;
public void run() {
Looper.prepare();
mHandler = new Handler() {
public void handleMessage(Message msg) {
// process incoming messages here
}
};
Looper.loop();
}
}
I suggest you read the Chapter 5 of Meike G.B. Android Concurrency. It will give you a comprehensive insight into the Looper/Handler framework. It is also great to browse the source code while you are reading, it is rather simple and self-explanatory.
Upvotes: 6
Reputation: 20400
Within Swing you would use
https://docs.oracle.com/javase/8/docs/api/javax/swing/SwingUtilities.html#invokeLater-java.lang.Runnable-
to run something on the main thread.
In general Java, an ExecutorService is like a thread pool and allows you to submit Runnable or Callable instances
https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html
However, if you aren't using an ExecutorService or Swing, there is no standard Java API to tell another thread to do something.
Upvotes: 0