I know that run method should not be called to start a new thread execution, but i was referring this article where they have called runnable.run();
inside another run method and it seems to be implying that it starts a new thread or its not at all creating threads, it just creates a new thread and runs all runnable in the same thread i.e task by task?
here is the code that article refers about.
public class ThreadPool {
private BlockingQueue taskQueue = null;
private List<PoolThread> threads = new ArrayList<PoolThread>();
private boolean isStopped = false;
public ThreadPool(int noOfThreads, int maxNoOfTasks){
taskQueue = new BlockingQueue(maxNoOfTasks);
for(int i=0; i<noOfThreads; i++){
threads.add(new PoolThread(taskQueue));
}
for(PoolThread thread : threads){
thread.start();
}
}
public synchronized void execute(Runnable task) throws Exception{
if(this.isStopped) throw
new IllegalStateException("ThreadPool is stopped");
this.taskQueue.enqueue(task);
}
public synchronized void stop(){
this.isStopped = true;
for(PoolThread thread : threads){
thread.doStop();
}
}
}
and
public class PoolThread extends Thread {
private BlockingQueue taskQueue = null;
private boolean isStopped = false;
public PoolThread(BlockingQueue queue){
taskQueue = queue;
}
public void run(){
while(!isStopped()){
try{
Runnable runnable = (Runnable) taskQueue.dequeue();
runnable.run();
} catch(Exception e){
//log or otherwise report exception,
//but keep pool thread alive.
}
}
}
public synchronized void doStop(){
isStopped = true;
this.interrupt(); //break pool thread out of dequeue() call.
}
public synchronized boolean isStopped(){
return isStopped;
}
}
questions:
Why thread.start(); is called inside constructor?
How do i enque my task if thread.start(); is called even before calling this.taskQueue.enqueue(task);
To understand all these please post a driver class for this example with maxNoOfTasks=10 and noOfThreads=3.and output for the same would be much appreciated.
thanks
The run() method is available in the thread class constructed using a separate Runnable object. Otherwise, this method does nothing and returns. We can call the run() method multiple times.
No, you can not directly call run method to start a thread. You need to call start method to create a new thread. If you call run method directly , it won't create a new thread and it will be in same stack as main.
But if we directly call the run() method then no new thread will be created and run() method will be executed as a normal method call on the current calling thread itself and no multi-threading will take place.
If run() method is called directly instead of start() method in Java code, run() method will be treated as a normal overridden method of the thread class (or runnable interface). This run method will be executed within the context of the current thread, not in a new thread.
i was referring this article where they have called
runnable.run()
; inside another run method and it seems to be implying that it starts a new thread.
Looking at the code, I don't see that implication at all.
It's not starting a new thread. It's running the next Runnable
from a queue on the current pool thread.
I know that run method should not be called to start a new thread execution...
Not should not, cannot. :-) Calling run
just calls run
, on the current thread, just like any other method call.
- Why
thread.start();
is called inside constructor?
To start the thread that was just created with new PoolThread(taskQueue)
.
- How do i enque my task if
thread.start();
is called even before callingthis.taskQueue.enqueue(task);
You pass it into execute
. It gets added to the queue of things to do (taskQueue
). One of the PoolThread
s that ThreadPool
created will pick it up when it's next free.
- To understand all these please post a driver class for this example with maxNoOfTasks=10 and noOfThreads=3.and output for the same would be much appreciated.
I don't know what you mean by a driver class, but I think answering the questions is sufficient.
- Does
Runnable.run()
inside run method start a new thread ?
No.
So to understand what this does, say you create a ThreadPool
with 5 threads. The ThreadPool
constructor creates and starts five PoolThread
threads immediately. Those threads constantly check taskQueue
to see if there's anything to do and, if so, they do it.
Initially, of course, taskQueue
is always empty so the threads are busy-waiting, constantly spinning checking for something in taskQueue
. (This isn't really ideal, it burns CPU for no good reason. It would be better to suspend threads when there's nothing to do, but that's starting to get pretty far from the actual question.)
Then, at some point, you call execute
and pass in a task. That adds it to the taskQueue
. The next time one of the five threads checks for something in taskQueue
, it finds it, and runs it on that thread (not a new one).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With