First, you can create for each consumer and after the consumer will finish it's job than the consumer will finish the run function and will die, so no need for infinite loop. however, creating thread for each consumer is not good idea since creation of thread is quite expensive in performance point of view. threads are very expensive resources. In addition, i agree with the answers above that it is better to implement runnable and not to extends thread. extend thread only when you wish to customize your thread.
I strongly suggest you will use thread pool and the consumer will be the runnable object that ran by the thread in the thread pool.
the code should look like this:
public class ConsumerMgr{
 int poolSize = 2;
int maxPoolSize = 2;
long keepAliveTime = 10;
ThreadPoolExecutor threadPool = null;
final ArrayBlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(
        5);
public ConsumerMgr()
{
    threadPool = new ThreadPoolExecutor(poolSize, maxPoolSize,
            keepAliveTime, TimeUnit.SECONDS, queue);
}
public void runTask(Runnable task)
{
    // System.out.println("Task count.."+threadPool.getTaskCount() );
    // System.out.println("Queue Size before assigning the
    // task.."+queue.size() );
    threadPool.execute(task);
    // System.out.println("Queue Size after assigning the
    // task.."+queue.size() );
    // System.out.println("Pool Size after assigning the
    // task.."+threadPool.getActiveCount() );
    // System.out.println("Task count.."+threadPool.getTaskCount() );
    System.out.println("Task count.." + queue.size());
}