Reputation: 6614
i have implemented a Runnable interface to load the image tiles and i want to call the Main thread from this secondary thread for displaying the tiles. can anybody tell me how to call a Main thread from a Runnable Interface thread in Java.
thanks.
Upvotes: 6
Views: 7244
Reputation: 26132
I think by "call the thread" the author meant some kind of callback from the working thread to the main thread to notify it about some kind of event.
There are a lot of ways to implement that kind of callback but I'd use a simple listener interface. Something like this:
//Interface of the listener that listens to image load events
public interface ImageLoadListener {
void onImageLoadSuccess(ImageInformation image);
void onImageLoadFailed(ImageInformation image);
}
//Worker thread that loads images and notifies the listener about success
public class ImageLoader implements Runnable {
private final ImageLoadListener loadListener;
public ImageLoader(ImageLoadListener listener) {
this.loadListener = listener;
}
public void run() {
....
for (each image to load) {
....
if (load(image)) {
if (loadListener != null) {
loadListener.onImageLoadSuccess(image);
}
} else {
if (loadListener != null) {
loadListener.onImageLoadFailed(image);
}
}
}
}
}
//Main class that creates working threads and processes loaded images
public class MainClass {
...
//Main method for processing loaded image
void showImageAfterLoad(ImageInformation information) {
...
}
//Some button that should create the worker thread
void onSomeButtonClick() {
//Instantiate the listener interface. If image load is successful - run showImageAfterLoad function on MainClass
ImageLoadListener listener = new ImageLoadListener() {
void onImageLoadSuccess(ImageInformation image) {
MainClass.this.showImageAfterLoad(image);
}
void onImageLoadFailed(ImageInformation image) {
//Do nothing
}
};
//Create loader and it's thread
ImageLoader loader = new ImageLoader(listener);
new Thread(loader).start();
}
}
In case you need it to be scalable then I'd recommend to swap to some implementation of Event Bus pattern. For example: http://code.google.com/p/simpleeventbus/
Event bus is generally the same thing as I wrote in my example but very scalable. Main difference is you can manage various kinds of events and register lots of listeners at once.
Upvotes: -1
Reputation: 500327
You can't really "call" one thread from another. What you can do is to have a queue of messages: the secondary thread would put messages onto the queue and the main thread would pick them up off the queue and process.
Upvotes: 0
Reputation: 64632
Instead of Runnable
you can use Callable<Set<Image>>
which returns a set of loaded images. Submit this callable task to an executor, get the Future<Set<Image>>
and wait for the loading thread to finish its job.
For example:
Future<Set<Image>> future =
Executors.newSingleThreadExecutor().submit(new Callable<Set<Image>>()
{
@Override
public Set<Image> call() throws Exception
{
return someServiceThatLoadsImages.load();
}
});
try
{
Set<Image> images = future.get();
display(images);
} catch (Exception e)
{
logger.error("Something bad happened", e);
}
Upvotes: 4
Reputation: 420971
What do you mean by "call a thread"?
You probably want to somehow "notify" the main thread that the images have been loaded. You could this by for instance letting the main thread wait()
for the load thread to notify()
it that the images have been loaded.
Preferably however, you should use one of the more "high-level" concurrency classes in the java.util.concurrent
package. For instance Callable
and Future
as suggested by Boris Pavlović. There is a sample usage in the documentation of Future
.
Upvotes: 0