Reply
 
LinkBack Thread Tools Display Modes
  #1 (permalink)  
Old 11-13-2009, 09:02 PM
Member
 
Join Date: Oct 2009
Posts: 14
Rep Power: 0
kminev is on a distinguished road
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:

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.
Bookmark Post in Technorati
Reply With Quote
  #2 (permalink)  
Old 11-14-2009, 05:18 AM
travishein's Avatar
Senior Member
 
Join Date: Sep 2009
Location: Canada
Posts: 355
Rep Power: 1
travishein is on a distinguished road
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.


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
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.
Bookmark Post in Technorati
Reply With Quote
  #3 (permalink)  
Old 11-15-2009, 05:36 PM
Member
 
Join Date: Oct 2009
Posts: 14
Rep Power: 0
kminev is on a distinguished road
Default
Thank you very much, this is exactly what I am looking for?
Bookmark Post in Technorati
Reply With Quote
  #4 (permalink)  
Old 11-15-2009, 05:38 PM
Member
 
Join Date: Oct 2009
Posts: 14
Rep Power: 0
kminev is on a distinguished road
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.
Bookmark Post in Technorati
Reply With Quote
  #5 (permalink)  
Old 11-15-2009, 05:56 PM
travishein's Avatar
Senior Member
 
Join Date: Sep 2009
Location: Canada
Posts: 355
Rep Power: 1
travishein is on a distinguished road
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:
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);
Bookmark Post in Technorati
Reply With Quote
  #6 (permalink)  
Old 11-16-2009, 06:03 PM
Member
 
Join Date: Oct 2009
Posts: 14
Rep Power: 0
kminev is on a distinguished road
Default
Hey thank you very much you answered all of my questions.
Bookmark Post in Technorati
Reply With Quote
  #7 (permalink)  
Old 11-18-2009, 04:22 PM
Member
 
Join Date: Oct 2009
Posts: 14
Rep Power: 0
kminev is on a distinguished road
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.
Bookmark Post in Technorati
Reply With Quote
  #8 (permalink)  
Old 11-18-2009, 07:06 PM
travishein's Avatar
Senior Member
 
Join Date: Sep 2009
Location: Canada
Posts: 355
Rep Power: 1
travishein is on a distinguished road
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.
Bookmark Post in Technorati
Reply With Quote
  #9 (permalink)  
Old 11-18-2009, 07:11 PM
Member
 
Join Date: Oct 2009
Posts: 14
Rep Power: 0
kminev is on a distinguished road
Default
I just used the join(milliseconds)

Thank you again for your thorough post.
Bookmark Post in Technorati
Reply With Quote
Reply

Bookmarks

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On


Similar Threads
Thread Thread Starter Forum Replies Last Post
Multi-Threading and process control in Java mo_mughrabi Advanced Java 2 08-16-2009 02:47 PM
Can you print direct to printer? tghn2b New To Java 0 02-26-2009 09:58 AM
Order Management System Java Developer NYC-Core Java/Multi-threading/Socket Developer evanp Jobs Offered 0 07-22-2008 05:39 PM
question about Multi threading in Java fred Advanced Java 1 07-24-2007 02:55 AM


All times are GMT +2. The time now is 05:05 AM.



VBulletin, Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2009, Crawlability, Inc.
Copyright ©2006 - 2007, www.java-forums.org