Bernard Bernard - 1 month ago 6
Java Question

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 a

Thread
After calling the
start()
as you know it will call the
run()
function in the
Runnable
class. In the
run()
function I want the thread stays as long as it receive the "Bye" message from the client. If i put them in the while loop it takes heaps of memory i think and I'm not using the power of thread. By the way i don't want my thread sleep in the run function by calling
Thread.sleep(6000);
Is there any other way to stay there in the run function?


  1. If the answer is join where and how and use it? Should I pop it at the beginning of the run function and it stays there until I send the "Bye" from client?

  2. Should I say
    while((request=in.readLine())!=null){
    ? It did not work because I think it will lose the connection with the client or better say client losing the connection?

  3. Should I say
    while(Thread.isAlive)
    and then kill the threat when I receive the "Bye" by calling
    Thread.stop
    which is little bit dangerous?



Here is my simplified code:

while(true)
{
ClientWorker w;
try
{
w = new ClientWorker(serverSocket.accept());
Thread t = new Thread(w);
t.start();
}
...... }

class ClientWorker implements Runnable {
public ClientWorker(Socket incoming)
{
myList = my;
this.incoming = incoming;
}
public synchronized void run()
{
in = new BufferedReader(new InputStreamReader(incoming.getInputStream()));
.
.
..
...
}

Answer

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 becomes useless.

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

Comments