Pages

Tuesday, January 20, 2009

Threading for Performance I

I write a lot of jsp and servlet classes so I do not get to stretch my programming legs much. Recently I had the joy of threading a batch process that I wanted to speed up. This batch process was supposed to process all the files in the system. This could be upwards of 15,000 files. This process had to run fast so I new threading was applicable. Once I got into it I was surprised by how well threads were going to work out. This actually makes for a fairly easy algorithm. I can create a loop and spawn separate threads to work on each file. Since none of the files is shared and I can control the creation of threads I don't have to worry as much about the traditional thread gotchas like thread contention.

Since this process is kicked off by a Web request, I am creating a master thread that will spawn the worker threads in my loop. I want to do this so that I can allow the web request to return and report that the process has started. Each subsequent request should refresh a log page allowing the user to see the output from the threaded batch process.

My technique is to create my loop for all the files I want to process. As I spawn threads I want to check against a max number of threads I want running at any given time. I like to use 8

Worker worker = null;
Iterator it = documents.iterator();
int threadCount = 0;

//loop until documents are exhausted
while ( true )
{
// comment the sleep to
// allow full speed processing.
// it is used to simulate a long processing
// session with a small amount of files.
// this.sleep(300);

if (it.hasNext()
{
if (threadCount <> 8)
{
// invoke new worker thread on the next document
worker = new Worker(workerThreads, "work", it.next());
worker.start();
}
}
else
{
//no more files, we can leave
break;
}

threadCount = workerThreads.enumerate(threadEnum);
}
// wait until all threads are finished
threadCount = workerThreads.enumerate(threadEnum);
for (Thread thread : threadEnum)
{
if (thread != null)
{
thread.join();
}
}
This will process all the documents by firing off 8 worker threads at a time. Once all 8 are finished then 8 more are kicked of until the pool of files is depleted. This allows me to tune the number of files being processed at any one time.

This is a very easy way to use the capabilities of threading to process the files faster. Come back for Threading for Performance II and I will discuss how to report on the threaded process to subsequent requests against the servlet.

No comments:

Post a Comment