Reputation: 643
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
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
Reputation: 421360
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
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