After starting a thread how could we keep the run function running? I have bunch of ideas but I'm not sure which is more professional?

In the simplest case just let your run method do its work and terminate when appropriate, something like this:

public void run() {
    boolean running = true;
    while(running) {
        running = doWork();
        if (Thread.interrupted()) {
            return;
        }
    }
}

Here the process stops when the doWork() method returns false. It is also good style to allow your thread to be interrupted, especially if it needs to run for a long time, see this tutorial. For any of this to work, doWork() should return regularly. Note you cannot restart threads, once the run method has returned the thread is reclaimed by the system.

If you need more control over your threads you could create separate Worker and ThreadManager classes.

To let the ThreadManager terminate the Worker, create a volatile boolean field in your Worker which is checked periodically:

public class Worker extends Thread {

    private volatile boolean running;

    public void run() {
        running = true;
        while(running) {
            running = doWork();
            if (Thread.interrupted()) {
                return;
            }
        }
    }

    public void stopRunning() {
        running = false;
    }
}

The Worker ends when interrupted or when the work is completed. Also the ThreadManager can request the Worker to stop by invoking the stopRunning() method.

If your thread runs out of work it could also call the wait() method on the ThreadManager. This pauses the thread until it is notified that there is new work to do. The ThreadManager should call notify() or notifyAll() when new work arrives (ThreadManager is used as a monitor in this example).

With this approach you can keep the Worker simple and only concerned with doing the work. The ThreadManager determines the number of threads and makes work available to them but does not need to know details of the actual work. One step further would be to split out 'work' into a separate class too, which you could call Job. An example of this can be found in my webcrawler example. This could be useful for passing new work from the ThreadManager to the worker thread.

EDIT: clarification: If the thread doesn't do any work and just needs to wait for some condition, don't use an iteration to wait, but use either wait/notify (see the webcrawler example I gave) or a simple callback when the condition arises.


I know this is late, but this is a much better implementation and avoids heavy CPU usage by busy waiting - Allows context switching when the thread is waiting for a signal.

Setting the semaphore to a value of 0 ensures that when the thread attempts to acquire permission to continue, it does not get it and waits. When you release the semaphore, the count is increased by 1, allowing the thread to continue and the count is decreased back to 0.

In main:

Semaphore sem = new Semaphore(0);
Worker t = new Worker(sem);
t.start();'

// The thread is now running but waiting, signal the semaphore to start work
sem.release();

The Thread

public class Worker(Semaphore sem) extends Thread {

    public void run() {
        sem.acquire();
        doWork();
    }
}

just return from the run() when you get "bye"