How to know when a thread has completed its task - java

As I am using gui and I need to create a thread to complete a task. See I want to display a dialog letting the user know the task has been completed I have tried
if(!thread.isAlive()) {
JOptionPane.showMessageDialog(null, "Done");
}
But that doesnt work.
Can anyone help me
Thanks

One option is to do your work using a SwingWorker. Override the done() method and have it notify your GUI that work is complete.
A simple example that nearly matches your use case is shown in the Javadocs at the top of the page:
final JLabel label;
class MeaningOfLifeFinder extends SwingWorker<String, Object> {
#Override
public String doInBackground() {
// Here you do the work of your thread
return findTheMeaningOfLife();
}
#Override
protected void done() {
// Here you notify the GUI
try {
label.setText(get());
} catch (Exception ignore) {
}
}
}

You could just have the thread print a message as it's last line of code in it's run method:
Thread thread = new Thread() {
#Override
public void run() {
//whatever you want this thread to do
//as the last line of code = the thread is going to terminate
JOptionPane.showMessageDialog(null, "Done");
}
}
thread.start();
If you want the main thread to wait for the thread to finish, in the main thread's code you'd use:
thread.join();

create a listener in your main Thread, and then program your Thread to tell the listener that it has completed.
public interface ThreadCompleteListener {
void notifyOfThreadComplete(final Thread thread);
}
then create the following class:
public abstract class NotifyingThread extends Thread {
private final Set<ThreadCompleteListener> listeners
= new CopyOnWriteArraySet<ThreadCompleteListener>();
public final void addListener(final ThreadCompleteListener listener) {
listeners.add(listener);
}
public final void removeListener(final ThreadCompleteListener listener) {
listeners.remove(listener);
}
private final void notifyListeners() {
for (ThreadCompleteListener listener : listeners) {
listener.notifyOfThreadComplete(this);
}
}
#Override
public final void run() {
try {
doRun();
} finally {
notifyListeners();
}
}
public abstract void doRun();
}
NotifyingThread thread1 = new OneOfYourThreads();
thread1.addListener(this); // add ourselves as a listener
thread1.start(); // Start the Thread
then, as each Thread exits, your notifyOfThreadComplete method will be invoked with the Thread instance that just completed. So now you can run any of your code in this method.

Use Callable thread. It will return value,So we can identify that it completed its task.

Related

How to run a task on a specific thread which is active?

Is there a way I can do a similar task like the android OS or java AWT thread where a task is run on a particular thread regardless of which thread of which thread the method was called from e.g. repaint().
private Thread thread;
public void startThread(){ //method which start's my thread
thread = new Thread(new Runnable(){
doSomething();
});
thread.start()
}
public void submitTask(Runnable runnable){
//run the runnable task on the thread "thread"
}
How can I achieve something like this, on a situation where I have more then one active thread
How I've dealt with this scenario before is to create a work queue and a thread which processes tasks that get added to it. So any thread can add a work item to the queue and the same thread will process it regardless of what thread added the work item.
public class MyClass {
private LinkedBlockingQueue<MyTask> myTaskProcessingQueue;
public MyClass() {
myTaskProcessingQueue = new LinkedBlockingQueue<MyTask>();
new MyTaskWorker().start();
}
public void processTask(MyTask myTask) {
myTaskProcessingQueue.put(myTask);
}
private class MyTaskWorker extends Thread {
#Override
public void run() {
while (true) {
try {
processMyTask(myTaskProcessingQueue.take());
} catch (InterruptedException ie) {
// handle it
}
}
}
private void processMyTask(MyTask myTask) {
// do work
}
}
}

Thread wait in Android

i have one problem with handling the thread in android ,in my class i have to create one thread which create some UI after that thread finish i will get some value ,here i want to wait my Main Process until the thread complete it process but when i put wait() or notify in Main process thread does not show the UI in my application
this is sample code
protected void onCreate(Bundle savedInstanceState) {
downloadThread = new MyThread(this);
downloadThread.start();
synchronized(this){
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
String test=Recognition.gettemp();
public class MyThread extends Thread {
private Recognition recognition;
public MyThread(Recognition recognition) {
this.recognition = recognition;
// TODO Auto-generated constructor stub
}
#Override
public void run() {
synchronized(this)
{
handler.post(new MyRunnable());
}
notifyAll();
}
}
}
static public class MyRunnable implements Runnable {
public void run() {
settemp(template);
}
}
}
public static String gettemp() {
return template;
}
public static void settemp(String template) {
Recognition.template = template;
}
}
here i will not use AsynTask because i have some other issue that is reason i choose Thread even now the problem is Thread wait do any give the suggestion for this
- Use java.util.CountDownLatch , here you can let some process complete before kick-off some other code.
- countDown() and await() will be of use to you.......
See this example of CountDownLatch:
http://www.javamex.com/tutorials/threads/CountDownLatch.shtml
Use the logic below :-
new Thread(new Runnable()
{
#Override
public void run()
{
//do the code here such as sending request to server
runOnUiThread(new Runnable()
{
#Override
public void run()
{
//do here the code which interact with UI
}
});
}
}).start();
What do you expect to happen if you freeze the main UI thread?
You should be using an ASyncTask to show your gui in the onPreExecute method, do the task in doInBackground then display the result in the onPostExecute method.
As a plus you can update the progress using onProgressUpdate too.
This is not an solution just a advice on how should you structure you activity/app.
You should never block the main thread by calling wait() its a bad user experience and not advised. It would also case a Android Not Responding (ANR) popup.
You can have you thread updating the UI from the background and let the UI to be responsive. Load the static part of your UI in onCreate() and then fire up the background thread to lazy load rest of the component.

Custom Functions in Thread

I have a simple Question:
I have a Thread named rlMF. I created it this way:
public Thread rlMF = new Thread(new Runnable() {
public void run() {
reloadMissingFiles();
stopTh();
}
public void stopTh() {
activityStopped = true;
}
});
Now i want to call the stopTh Function from outer Thread. Why can't i simply call rlMF.stopTh(); and what can i do else?
Example:
protected void onPause() {
Log.d("Info", "destroying...");
activityStopped = true;
rlMF.stopTh();
super.onPause();
}
Is not working...
Because the interface accessible is from Thread. In order to have you method accessible from out, you need to specify a type that exposes this method.
And if you take a look carefully the method is implemented in the instance of Runnable. Not even in Thread.
You could have something like this if you really need to access the Runnable object:
class MyRunnable implements Runnable {
public void run() {
...
}
public void fooBar() {
...
}
}
public void someMethod() {
MyRunnable myRunnable = new MyRunnable();
Thread thread = new Thread(myRunnable);
...
myRunnable.fooBar();
...
}
An example for Francisco approach, besides what you are trying to achieve. Maybe this can point you in the right direction
public class CustomRun implements Runnable {
public void run() {
reloadMissingFiles();
stopTh();
}
public void stopTh() {
activityStopped = true;
}
}
In your Code
// start thread with custom runner
CustomRun runner = new CustomRun();
new Thread(runner).start();
// call your stopTh method on CustomRun class
protected void onPause() {
Log.d("Info", "destroying...");
activityStopped = true;
runner.stopTh();
super.onPause();
}
Your goal is to interrupt the thread from onPause. There are several ways to do it, but essentially, you will need to include some interruptibility in reloadMissingFiles.
Option 1
You can use a boolean flag like you did - you need to declare it as volatile to make sure the changes are visible across threads:
private volatile boolean activityStopped = false;
public void reloadMissingFiles() {
while (!activityStopped) {
//load small chunks so that the activityStopped flag is checked regularly
}
}
public Thread rlMF = new Thread(new Runnable() {
public void run() {
reloadMissingFiles(); //will exit soon after activityStopped has been set to false
}
});
protected void onPause() {
//This will stop the thread fairly soon if the while loop in
//reloadMissingFiles is fast enough
activityStopped = true;
super.onPause();
}
Option 2 (better approach)
I don't know what you do in reloadMissingFiles, but I suppose it is some sort of I/O operations, which are generally interruptible. You can then have an interruption policy where you stop as soon as an InterruptedException is caught:
public void reloadMissingFiles() {
try {
//use I/O methods that can be interrupted
} catch (InterruptedException e) {
//cleanup specific stuff (for example undo the operation you started
//if you don't have time to complete it
//then let the finally block clean the mess
} finally {
//cleanup (close the files, database connection or whatever needs to be cleaned
}
}
public Thread rlMF = new Thread(new Runnable() {
public void run() {
reloadMissingFiles(); //will exit when interrupted
}
});
protected void onPause() {
runner.interrupt(); //sends an interruption signal to the I/O operations
super.onPause();
}
Note: you can also read this article for a more in depth version of it.

Swing updating UI components while the job is running

I am developing a swing applciation. In that I have a workflow of jobs to be done.
I Am running these jobs in a for loop one after the other. The interesting thing is I have to update GUI status bar with the current job name running.
I can not use SwingUtilities.invokeAndWait as it can not run on the dispatch thread which will be the currently running thread.
I tried using SwingWorker since the jobs are running in a loop, the SwingWorker's doBackGrount() method will execute and will come out and gets the the next index to run the next job. In the done() of SwingWorker I have written code to update GUI with the status.
public class TestAction extends SwingWorker<Boolean, Void> {
boolean executeThread = false;
public TestAction() {
}
#Override
protected Boolean doInBackground() throws Exception {
executeThread = ExecuteWebServiceAction.webServiceExecution();
return executeThread;
}
#Override
protected void done() {
try {
boolean isOver = (boolean) get();
if (isOver) {
MainApplication.getInstance().getFrame().setStatus(LangUtil.getString("cdsExecuteFinehed")
+ " " + ((WebServiceTool) DrawingManager.getInstance().getCurrentTool()).getName());
FrameMain.jPanel6.repaint();
}
} catch (Interr`enter code here`uptedException ex) {
Logger.getLogger(TestAction.class.getName()).log(Level.SEVERE, null, ex);
} catch (ExecutionException ex) {
Logger.getLogger(TestAction.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
And this is where am calling TestAction:
if (!WorkFlow.isIsWorkflow()) {
SwingUtilities.invokeLater(
new Runnable() {
#Override
public void run() {
webServiceExecution();
}
});
} else {
new TestAction().execute();
}
running in a loop one after the other and notify UI when one is done
sounds like "big job with intermediate results". Intermediate results are supported via the publish/process methods:
implement doInBackground to loop through the jobs and call publish when one is terminated
implement process to do the ui update
you can use Thread.currentThread().sleep(5000); in SwingWorker's doInBackground method before currentthread finishes its execution and update your UI
You could add a Runnable to your constructor to be run when done() is over:
public class TestAction extends SwingWorker<Boolean, Void> {
boolean executeThread = false;
private final Runnable runWhenDone;
public TestAction(Runnable runWhenDone) {
this.runWhenDone = runWhenDone;
}
//...
#Override
protected void done() {
try {
boolean isOver = (boolean) get();
if (isOver) {
MainApplication.getInstance().getFrame().setStatus(LangUtil.getString("cdsExecuteFinehed")
+ " " + ((WebServiceTool) DrawingManager.getInstance().getCurrentTool()).getName());
//Run the Runnable here
runWhenDone.run();
//...
And in your GUI class
Runnable r = new Runnable() {public void run() {updateTheTitle();}};
(new TestAction(r)).execute();
private void updateTheTitle() { yourTitle.setText("I am done");}

How to properly stop a "drawing" thread

A thread:
public class DrawThread extends Thread {
private RMapCanvas canvas;
final Handler myHandler = new Handler();
final ArrayList<RGroupMapLayer> layers;
public DrawThread(RMapCanvas aCanvas, ArrayList<RGroupMapLayer> arrayOfLayers)
{
canvas = aCanvas;
layers = arrayOfLayers;
}
public void run() {
activity.RaiseNotification(activity.getApplicationContext().getResources().getString(R.string.loading).toString());
for (RGroupMapLayer l : layers)
{
l.validateAndRepairView(false, canvas.renderer, canvas.mapView);
l.render(canvas.renderer, canvas.mapView, canvas.mapEvent, 5000000, 5000000);
if (settings.getPositionFeature() != null)
{
RPointFeatureStyle positionStyle = new RPointFeatureStyle(RPointFeatureStyle.SIMPLE_POINT_STYLE_GPS);
positionStyle.render(settings.getPositionFeature(), renderer, mapView);
}
myHandler.post(new Runnable() {
#Override
public void run() {
canvas.RenderComplete();
}});
}
activity.statusMessage.cancel();
}
public synchronized void requestStop() {
activity.statusMessage.cancel();
this.interrupt();
}
}
Calling the requestStop that interrupts a thread is not enough. The thread just keeps running. Can some one please update the code to show me the correct way of stopping this thread? And by the way ... the RenderComplete() methods updates the UI (witch is a problem in my case, because "old" threads keep updating the UI even if new one is starter and the old one interrupted).
Thanx in advance.
In general interrupting or stoping threads by yourself is not recommended. Your thread should have a flag inside the run method. When the flag is true - the thread is running, when the flag is false - thread is also running, but now it doesn't do anything. The system will stop this thread when needed. Here's how it should look:
public void run() {
while (flag) {
//do your work
}
}
And to "stop" the thread just use flag = false;
Hope this helps.

Categories

Resources