3

I would like to ask basic question about Java threads. Let's consider a producer - consumer scenario. Say there is one producer, and n consumer. Consumer arrive at random time, and once they are served they go away, meaning each consumer runs on its own thread. Should I still use run forever condition for consumer ?

public class Consumer extends Thread {
    public void run() {
        while (true) {
        }
    }
}

Won't this keep thread running forever ?

1
  • Not sure I understand your question. This thread will indeed run forever. Whether or not to use a run-forever condition is completely down to you. Commented Nov 8, 2011 at 20:19

7 Answers 7

3

I wouldn't extend Thread, instead I would implement Runnable.

If you want the thread to run forever, I would have it loop forever.

A common alternative is to use

while(!Thread.currentThread().isInterrupted()) {

or

while(!Thread.interrupted()) {
Sign up to request clarification or add additional context in comments.

4 Comments

Does this give guarantee that others thread (consumer who are not served) won't die early ?
Having one thread stop another isn't something which just happens. Actually its something which isn't that simple to do. Can you explain why you would be concerned that other threads might die?
Glad you asked. I am new to Java and OOP for that matter. Say there are 5 consumer at any given time, and they are waiting to be served by producer. So, obviously there will be 5 consumer threads. Since Thread.interrupted() is a static method, if one thread interrupts wouldn't it cause all other threads to die as well ?
Each thread has its own interrupted flag. There is no simple way to interrupt every thread.
1

It will, so you might want to do something like

while(beingServed)
{
    //check if the customer is done being served (set beingServed to false)
}

This way you'll escaped the loop when it's meant to die.

Comments

1

Why not use a boolean that represents the presence of the Consumer?

public class Consumer extends Thread {
    private volatile boolean present;

    public Consumer() {
        present = true;
    }

    public void run() {
        while (present) {
            // Do Stuff
        }
    }

    public void consumerLeft() {
        present = false;
    }
}

2 Comments

present should be volatile. ;)
@PeterLawrey I knew I forgot something :P
1

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());

}

Comments

0

It is not a good idea to extend Thread (unless you are coding a new kind of thread - ie never).

The best approach is to pass a Runnable to the Thread's constructor, like this:

public class Consumer implements Runnable {

    public void run() {
        while (true) {
            // Do something
        }
    }
}

new Thread(new Consumer()).start();

In general, while(true) is OK, but you have to handle being interrupted, either by normal wake or by spurious wakeup. There are many examples out there on the web.

I recommend reading Java Concurrency in Practice.

1 Comment

What is wake? And how do you trigger a spurious wakeup? Isn't a spurious wakeup, by definition, a wakeup that hasn't been caused by code?
0

for producer-consumer pattern you better use wait() and notify(). See this tutorial. This is far more efficient than using while(true) loop.

1 Comment

It would be even better and simpler to use a BlockingQueue.
0

If you want your thread to processes messages until you kill them (or they are killed in some way) inside while (true) there would be some synchronized call to your producer thread (or SynchronizedQueue, or queuing system) which would block until a message becomes available. Once a message is consumed, the loop restarts and waits again.

If you want to manually instantiate a bunch of thread which pull a message from a producer just once then die, don't use while (true).

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.