Hi all,

I have a multi-threaded program. This program, lets say spawns 10 threads. I would like to update a variable when each thread finishes its job.

The reason why I am asking this, is because I would like to show something like progress bar (not really a progress bar, but display a precentage of job completion, while the program is running).

I have this thaugh, and someone please correct me if I am wrong.

I have the following classes

- MainProgram.java
- MainProgramThread.java
- MainProgramProgressThread.java

If MainProgram creates 10 instance of MainProgramThread class, I would like to decrement a counter (which has the maximum number of threads running)

On the other hand, MainProgramProgressThread class will only display the progress percentage (this will be calculated) so long as the number of counter is greater than zero when this value reaches 0, then I would like the ProgressThread to stop.

So, my question is how can I know when a thread ends?

Or if there's another way of doing what I would like to do, I am open to ideas.

Thanks in advance...

Inside the run method of the Thread class have a boolean method take value true when it finishes. That variable will be declared as an attribute of the class.

When you call the thread have a while loop checking that variable when it becomes true you will exit the loop

Thanks for the info.

So, lets consider the following code. Please correct me if I am wrong.

public class MainClass {
   int final MAX = 10;
   int counter = MAX;
   public static void main (String[] arg) {
      for (int i=0; i < MAX; i++) {
         ThreadClass tc = new ThreadClass();
         tc.start();
      }
   }

   public static synchronized void updateCounter() {
      counter--;
   }
   public int getCounter () {
      return counter;
   }
}

//----------------------------
public class ThreadClass extends Thread {
   public void run () {
      while (some condition is true) {
         doSomeOperationHere();
      }
      MainClass.updateCounter();
   }
}

//-------------------------------
public class ProgressThread extends Thread {
   public void run () {
      while (MainClass.getCounter() > 0) {
         // calculate and display progress bar
      }
   }
}

Will this work?

Thanks.

Here's one way you could monitor progress on the tasks. It involves timed polling of the progress of each task.

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.swing.ProgressMonitor;

public class ProgressDemo {

    public static void main(String[] args) {
        WorkQueue work = new WorkQueue();
        work.begin();
    }

    static class WorkQueue {

        final int NUM_THREADS = 5;
        ExecutorService execService = 
          Executors.newFixedThreadPool(NUM_THREADS);
        
        int totalThingsToDo = 0;
        int percentComplete = 0;

        public void begin() {
            totalThingsToDo = 100;
            List<LongTask> tasks = new ArrayList<LongTask>();
            
            // create and submit tasks to thread pool
            for (int i = 0; i < NUM_THREADS; i++) {
                LongTask task = 
                  new LongTask(totalThingsToDo/NUM_THREADS, i);
                tasks.add(task);
                execService.submit(task);
            }
            
            ProgressMonitor monitor = new ProgressMonitor(null, 
              "Doing stuff...", "", 0, 100);
            
            // monitor progress until done
            while (percentComplete < 100) {
                int partialProgress = 0;
                for (LongTask task : tasks) {
                    partialProgress += task.getProgress();
                }
                percentComplete = 
                  (int)(partialProgress / (float)tasks.size());
                
                try {
                    // wait one second between progress updates
                    Thread.sleep(1000);
                } catch (InterruptedException ie) {
                    Thread.currentThread().interrupt();
                }
                
                monitor.setNote(percentComplete+" %");
                monitor.setProgress(percentComplete);
            }
            // shutdown the thread pool
            execService.shutdown();
        }
    }

    /** Mock task that does an arbitrarty number
     * of "things" in a random amount of time.
     */
    static class LongTask implements Callable<Boolean> {

        int thingsToDo = 0;
        int thingsDone = 0;
        int taskId=0;

        public LongTask(int thingsToDo, int taskId) {
            this.thingsToDo = thingsToDo;
            this.taskId = taskId;
        }

        public Boolean call() throws Exception {
            boolean completed = false;
            while (thingsDone < thingsToDo) {
                // random pause to simulate "working" 
                Thread.sleep((int)(Math.random() * 3000));
                thingsDone++;
            }
            System.out.println(taskId + " done");
            return Boolean.valueOf(completed);
        }

        public int getProgress() {
            return (int)(thingsDone / (float)thingsToDo * 100f);
        }
    }
}

Alternately, you could provide a reference to the WorkQueue class to the tasks and a call-back method that each task could use to publish it's progress (basically making the WorkQueue a listener for progress updates generated by the tasks). An example of that implementation can be seen here in the Swing progress bar tutorial: http://java.sun.com/docs/books/tutorial/uiswing/components/progress.html

Thanks Ezzaral. I used a counter to determine whether each thread is finished. And it's working now.

Glad to hear it. I posted that example around the same time that you posted what you were trying, so there was a little overlap. It also went a little bit further than your stated goal of just using thread completion to increment progress, but the intent was to show a progress polling mechanism. Your own code basically uses the alternative mechanism I mentioned at the bottom of the post, with each thread calling back to a central method to report progress. Collectively those two mechanisms represent a push versus pull paradigm in the communication process.

This question has already been answered. Start a new discussion instead.