Noona
Noona

Reputation: 643

communication between threads in java: stopping a thread if another thread has finished

How can I make a thread run only if the other thread is running too, meaning, if I return from run in one thread, then I want the other to stop running too, my code looks something like this:

ClientMessageHandler clientMessagehandler = new ClientMessageHandler();
ServerMessageHandler serverMessagehandler = new ServerMessageHandler();
Thread thread1 = new Thread(serverMessagehandler);
Thread thread2 = new Thread(clientMessagehandler);
thread2.start();
thread1.start();

I want to cause thread1 to stop running when thread2 stops running.

edit: detecting when thread2 stops running in order stop thread1 from running, and not how to stop thread1 from running thanks

Upvotes: 0

Views: 6633

Answers (3)

Tim Bender
Tim Bender

Reputation: 20442

Edit for question clarification

I see two immediate options:

Option 1. Have the ClientMessageHandler implementation terminate the ServerMessageHandler as it terminates. This means the client needs a reference to the server thread.

public class ClientMessageHandler implements Runnable {
    Thread serverThread;
    public ClientMessageHandler(Thread srvThread) {
        this.serverThread = srvThread;
    }
    public void run() {
        try {
            while (true) { ... }
        } finally {
           serverThread.interrupt();
        }
   }
}

Option 2. Use thread2.join() or a CountDownLatch to wait for thread2 to terminate. When control returns from the join (or CountDownLatch#await()).

ClientMessageHandler clientMessagehandler = new ClientMessageHandler();
ServerMessageHandler serverMessagehandler = new ServerMessageHandler();
Thread thread1 = new Thread(serverMessagehandler);
Thread thread2 = new Thread(clientMessagehandler);
thread2.start();
thread1.start();

thread2.join(); //blocks until the client terminates
thread1.interrupt();

Make sure that inside thread1's run method, you have some logical place where you can check the interrupt status (Thread#isInterrupted()) and decide to terminate. Also, you must take care to handle InterruptedException properly and either terminate or reset the interrupt flag.

Upvotes: 2

aioobe
aioobe

Reputation: 421350

This minimal example should demonstrate the basic idea:

import java.io.*;
import java.util.concurrent.LinkedBlockingQueue;

public class Test {

    static LinkedBlockingQueue<String> msgBuf = new LinkedBlockingQueue<String>();
    static volatile boolean keepRunning = true;
    static Thread thread1, thread2;

    public static void main(String[] args) throws IOException {
        ClientMessageHandler clientMessagehandler = new ClientMessageHandler();
        ServerMessageHandler serverMessagehandler = new ServerMessageHandler();
        thread1 = new Thread(serverMessagehandler);
        thread2 = new Thread(clientMessagehandler);
        thread2.start();
        thread1.start();
    }

}

class ClientMessageHandler implements Runnable {
    public void run() {
        while (Test.keepRunning) {
            try {
                String msg = Test.msgBuf.take();
                System.out.println("Eating " + msg);
            } catch (InterruptedException ie) {
            }
        }
    }
}

class ServerMessageHandler implements Runnable {
    public void run() {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String in;
        try {
            while (!(in = br.readLine()).equals("quit")) {
                System.out.println("Feeding " + in);
                Test.msgBuf.offer(in);
            }
        } catch (IOException e) {
        }
        Test.keepRunning = false;
        Test.thread2.interrupt();
    }
}

Upvotes: 3

BalusC
BalusC

Reputation: 1109865

A Thread will only stop when the run() method returns. The Thread#interrupt() only signals that a request for interruption has made. You still have to write the code in run() method accordingly that it periodically checks Thread#isInterrupted() and handle accordingly. E.g. check for it on every unit of task the Thread is doing, or on every certain progress when sort of progresslistener is attached.

Upvotes: 1

Related Questions