is it possible to start a thread by calling run() inside a run()method?

  • A+
Category:Languages

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:

  1. Why thread.start(); is called inside constructor?

  2. How do i enque my task if thread.start(); is called even before calling this.taskQueue.enqueue(task);

  3. 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.

  4. Does Runnable.run() inside run method start a new thread ?

thanks

 


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.

  1. Why thread.start(); is called inside constructor?

To start the thread that was just created with new PoolThread(taskQueue).

  1. How do i enque my task if thread.start(); is called even before calling this.taskQueue.enqueue(task);

You pass it into execute. It gets added to the queue of things to do (taskQueue). One of the PoolThreads that ThreadPool created will pick it up when it's next free.

  1. 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.

  1. 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).

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: