Results 1 to 9 of 9
  1. #1
    kminev is offline Member
    Join Date
    Oct 2009
    Posts
    14
    Rep Power
    0

    Default Newbie to multi-threading please direct me :)

    Hi,

    As the title says I am new to java multi-threaded programming.

    Here is what I need to do. I need to execute multiple threads from a simple java method and then watch from the same method when all the executed threads are finished and as every thread ends this thread should pass a value back to my function.

    Could this be accomplished and if yes can someone direct how I can accomplish this.

    Here some of the code I am trying to get to work:

    Java Code:
    package executor;
    
    import java.io.*;
    
    class StreamGobbler extends Thread {
    
        InputStream is;
        String type;
    
        StreamGobbler(InputStream is, String type) {
            this.is = is;
            this.type = type;
        }
    
        @Override
        public void run() {
            try {
                InputStreamReader isr = new InputStreamReader(is);
                BufferedReader br = new BufferedReader(isr);
                String line = null;
                while ((line = br.readLine()) != null) {
                    System.out.println(type + ">" + line);
                }
            } catch (IOException ioe) {
                ioe.printStackTrace();
            }
        }
    }
    
    /**
     *
     * @author kminev
     */
    public class Main {
        /**
         * @param args the command line arguments
         */
        public static void main(String[] args) throws IOException, InterruptedException {
            // TODO code application logic here
    
            File f;
            Writer wr=null;
            f = new File("myScript.sh");
            if (!f.exists()) {
                f.createNewFile();
            }
    
            //StringBuilder sb = new StringBuilder();
            wr = new BufferedWriter(new FileWriter(f));
           wr.write("this goes to a bash script that will be executed as a thread");
            wr.close();
    
            String strCommand = "bash myScript.sh";
            //System.out.println("Command: " + strCommand);
    
            Runtime rt = Runtime.getRuntime();
            Process proc = rt.exec(strCommand);
    
            StreamGobbler errorGobbler = new StreamGobbler(proc.getErrorStream(), "ERROR");
            // any output?
            StreamGobbler outputGobbler = new StreamGobbler(proc.getInputStream(), "OUTPUT");
            System.out.println("KICK THEM OFF");
            // kick them off
            errorGobbler.start();
            outputGobbler.start();
            System.out.println("AFTER KICK OFF BLOCK");
            // any error???
            int exitVal = proc.waitFor();
            System.out.println("ExitValue: " + exitVal);
    
            if(exitVal == 0){
                f.delete();
            }
        }
    }

    If I have a for loop which will call the code in main x amount of times how can I know when all threads are return and most importantly return a values from each thread?


    Thanks in advance.

  2. #2
    travishein's Avatar
    travishein is offline Senior Member
    Join Date
    Sep 2009
    Location
    Canada
    Posts
    684
    Rep Power
    6

    Default

    to know when all threads have returned, we can use the 'join' method on the threads.

    For capturing the results, since the run() method doesn't return anything, and threads can return at any time out of order, we should likely invent a mechanism the thread can report its output to when its finished, such as initializing our thread with a spot to write its outputs to.


    Java Code:
    cass ResultBean {
      public int result;
    }
    
    class Worker implements Runnable {
      ResultBean resultBean;
    
      public Worker(ResultBean value) {
        this.resultBean = value;
      }
    
      public void run() {
        /* stuff the thread is supposed to do here */
        resultBean.result = 4; // set the result after thread executed.
      }
    }
    then in your execution function
    Java Code:
    Thread[] threads = new Thread[6]; // number of threads
    ResultBean[] results = new ResultBean[6];
    
    
    for (int i = 0; i < threads.length; i++) {
       results[i] = new ResultBean();
       threads[i] = new Thread(new Worker(results[i]));
       threads[i].start();
    }
    // done initializing threads
    
    
    // now wait for threads to finish
    for (int i = 0; i < threads.length; i++) {
      if (threads[i].isAlive() ) {
        threads[i].join();
      }
    }
    
    //the results[] array now should contain values set from each worker thread.

  3. #3
    kminev is offline Member
    Join Date
    Oct 2009
    Posts
    14
    Rep Power
    0

    Default

    Thank you very much, this is exactly what I am looking for?

  4. #4
    kminev is offline Member
    Join Date
    Oct 2009
    Posts
    14
    Rep Power
    0

    Default

    Actually another question from a newbie multi-thread programmer. :)

    In case one of my threads chokes for some reason or executes forever. How can manage that. Let say from 6 thread number 4 is in infinite loop how can I if for example one thread does not come back for x amount of seconds to terminate or what is a best practice on that subject?

    Thank you.

  5. #5
    travishein's Avatar
    travishein is offline Senior Member
    Join Date
    Sep 2009
    Location
    Canada
    Posts
    684
    Rep Power
    6

    Default

    I guess we could do this in the main thread, where instead of just waiting for the worker threads to complete with join(), we could have it do a wait up to the specified amount of wait time.

    From my previous example, replacing that last for loop where it joins on each thread simple join with:
    Java Code:
    //
    long maxWaitTime = 20000; // 20 seconds or what ever is your max thread run time
    
    long totalWaitTime = 0; // incremented by our loop below
    do {
      boolean running = false;
      for (int i = 0; i < threads.length; i++) {
        if (threads[i].isAlive() ) {
          running = true;
          break; // skips the for .. threads inner loop when at least one is still alive.
        }
      }
      
      if (running) {
        // at least one thread is still alive
        // wait a tiny bit of time, increment a total wait time counter.
        int smallWaitTime = 20 ; // milliseconds
        try {
          Thread.sleep(smalWaitTime);
        } catch (InterruptedException ex) { }
        totalWeightTime += smallWeightTime;
      
        // inspect the threshold of wait time, if threads have been running too long, kill the remaining running one(s)
       if (totalWeightTime >= maxWaitTime) {
        for (int i = 0; i < threads.length; i++) {
          if (threads[i].isAlive() ) {
            threads[i].interrupt();
          }
        } // for each thread
        break;
       } // exceeded max wait time 
      } // if running
    } while (running);

  6. #6
    kminev is offline Member
    Join Date
    Oct 2009
    Posts
    14
    Rep Power
    0

    Default

    Hey thank you very much you answered all of my questions.

  7. #7
    kminev is offline Member
    Join Date
    Oct 2009
    Posts
    14
    Rep Power
    0

    Default

    Hey thanks once again. I have one question well two :) about the code you posted for threads timing out.

    1) I don't see the join function, does it mean that we avoid it?
    2) The timeout time is that for each thread 20 seconds or for all of them?

    My problem is that sometimes my thread could hang which is ok due to bad user input or what not, however I need to set a threshold of time to interrupt the Thread so it does not crash my tomcat.

    Thank you.

  8. #8
    travishein's Avatar
    travishein is offline Senior Member
    Join Date
    Sep 2009
    Location
    Canada
    Posts
    684
    Rep Power
    6

    Default

    yes, in this last example the thread doesn't use join it will wait for the maximum amount of threshold time, as long as at least one thread is still alive. join normally means wait forever until the thread finishes. the test for isalive() will return false when all threads are completed and the waiting would stop.

    this also works for all threads, (but not in linear ordering like each thread 20 seconds).

    all threads are started at the same time, and run at the same time, up to the maximum threshold time, and any thread(s) that are still running at that point would be killed after that wait threshold.

    But if all threads are found to finish before the threshold time, the main loop stops waiting (its possible then the total wait time would be less than 20 seconds if all threads finished before)

    now this sample thread monitoring and kill it after a time threshold, assumes all threads were a constant number of threads, and all started at the same time.

    its likely better to have a single thread to be in charge of monitoring and killing all threads in your application, where when each thread is created, and when it is started, it would be registered with this single monitor thread, and the montor thread would keep a "total execution time" for each of individual threads it is monitoring, and do the kill of that thread after its defined threshold (by this logic each thread could have its own different timeout threshold too). since the monitor thread would never exit, the trick would be to have your threads register with it, and unregistered from it when the thread finishes itself, or when the monitor thread kills a long running / hung thread.

  9. #9
    kminev is offline Member
    Join Date
    Oct 2009
    Posts
    14
    Rep Power
    0

    Default

    I just used the join(milliseconds)

    Thank you again for your thorough post.

Similar Threads

  1. Multi-Threading and process control in Java
    By mo_mughrabi in forum Advanced Java
    Replies: 2
    Last Post: 08-16-2009, 01:47 PM
  2. Can you print direct to printer?
    By tghn2b in forum New To Java
    Replies: 0
    Last Post: 02-26-2009, 08:58 AM
  3. Replies: 0
    Last Post: 07-22-2008, 04:39 PM
  4. question about Multi threading in Java
    By fred in forum Advanced Java
    Replies: 1
    Last Post: 07-24-2007, 01:55 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •