Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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()));
.
.
..
...
}
like image 973
Bernard Avatar asked Oct 17 '12 13:10

Bernard


People also ask

How do you ensure that a thread runs after another?

By using join you can ensure running of a thread one after another.

What happens if a thread is started with the run method?

start method of thread class is implemented as when it is called a new Thread is created and code inside run() method is executed in that new Thread. While if run method is executed directly than no new Thread is created and code inside run() will execute on current Thread and no multi-threading will take place.


1 Answers

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.

like image 174
Adriaan Koster Avatar answered Sep 23 '22 02:09

Adriaan Koster