The Thread-Per-Message design is the simplest concurrency technique wherein where a thread is created for each incoming request. The benefits of creating a new thread to handle each request should outweigh the corresponding thread creation overheads. This design is generally recommended over sequential executions for time consuming, I/O bound, session based or isolated tasks.
Wiki Markup |
---|
On the other hand, there can be several disadvantages of this design such as creation overhead in case of frequent or recurring requests, significant processing overhead, resource exhaustion pertainingof to threads (leading to the {{OutOfMemoryError}}), thread scheduling and context switching overhead \[[Lea 00|AA. Java References#Lea 00]\]. |
Thread Pools overcome these disadvantages as the maximum number of worker threads that can be initiated and executed simultaneously , can be controlled. Every worker accepts a Runnable
object from a request and stores it in a temporary Channel
like a buffer or a queue until resources become available. Because threads are reused and can be efficiently added to the Channel
, most of the thread creation overhead is eliminated.
...
Wiki Markup |
---|
According to the Java API \[[API 06|AA. Java References#API 06]\] for the interface {{java.util.concurrent.Executor}}\[[Executor|http://java.sun.com/javase/6/docs/api/java/util/concurrent/Executor.html]\]: |
Wiki Markup |
---|
\[The Interface {{Executor}} is\] An object that executes submitted {{Runnable}} tasks. This interface provides a way of decoupling task submission from the mechanics of how each task will be run, including details of thread use, scheduling, etc. An {{Executor}} is normally used instead of explicitly creating threads. |
Code Block |
---|
|
import java.util.concurrent.Executors;
class GetRequest {
protected final Helper h = new Helper();
String request;
public synchronized String accept() {
String data = "Read data from pipe";
//read the request data, else block
return data;
}
public void request() {
int NoOfThreads = 200;
Executor exec = (Executor) Executors.newFixedThreadPool(NoOfThreads);
while(true) {
request = accept();
exec.Executeexecute(new Runnable() {
public void run() {
h.handle(request);
}
});
}
}
}
|
...
Wiki Markup |
---|
This noncompliant code example shows a _thread starvation deadlock_. This situation not only occurs in singesingle threaded Executors, but also in those with large Thread Pools. This can happen when all the threads executing in the pool are blocked on tasks that are waiting on the queue. A blocking operation within a subtask can also lead to unbounded queue growth. \[[Goetz 06|AA. Java References#Goetz 06]\] |
...