java中线程之间的通信:如果另一个线程已经完成,则停止一个线程

时间:2010-05-12 03:48:53

标签: java multithreading

如果另一个线程也在运行,我怎样才能运行一个线程,这意味着,如果我从一个线程中运行返回,那么我希望另一个线程也停止运行, 我的代码看起来像这样:

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

我希望thread1thread2停止运行时停止运行。

编辑:检测thread2何时停止运行,以阻止thread1停止运行,而不是如何阻止thread1运行 感谢

3 个答案:

答案 0 :(得分:3)

这个最小的例子应该展示基本的想法:

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();
    }
}

答案 1 :(得分:2)

编辑问题澄清

我看到两个直接的选择:

选项1.让ClientMessageHandler实现在终止时终止ServerMessageHandler。这意味着客户端需要对服务器线程的引用。

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

选项2.使用thread2.join()CountDownLatch等待thread2终止。当控件从连接返回时(或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();

确保在thread1的run方法中,你有一个逻辑位置可以检查中断状态(Thread#isInterrupted())并决定终止。此外,您必须注意正确处理InterruptedException并终止或重置中断标志。

答案 2 :(得分:1)

Thread只会在run()方法返回时停止。 Thread#interrupt()仅表示请求中断。您仍然需要在run()方法中编写代码,以便定期检查Thread#isInterrupted()并相应地处理。例如。在Thread正在执行的每个任务单元上检查它,或者在附加了progresslistener类型的每个特定进度上检查它。