【问题标题】:communication between threads in java: stopping a thread if another thread has finishedjava中线程之间的通信:如果另一个线程完成则停止一个线程
【发布时间】:2010-05-12 03:48:52
【问题描述】:

我怎样才能让一个线程只有在另一个线程也在运行时才运行,这意味着,如果我从一个线程中运行返回,那么我希望另一个也停止运行, 我的代码如下所示:

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 运行 谢谢

【问题讨论】:

    标签: java multithreading


    【解决方案1】:

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

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

    【讨论】:

      【解决方案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 等待线程 2 终止。当控制从连接(或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,并终止或重置中断标志。

      【讨论】:

      • 它不会立即停止...Edit 是的,以后再编辑它。
      • @BalusC 是的,我知道,我正在尝试 Tom Hawtin 的博客。
      • 我的意思是,检测thread2何时停止运行以停止thread1运行,而不是如何停止thread1运行
      • @Noona,我做了一些重要的编辑来弥补你的澄清。a
      【解决方案3】:

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

      【讨论】:

      • Thread2 不会被中断,它只是从它的 run 方法返回,我尝试在 clientMesasgehandler 中传递一个参数,并在 servertMesasgehandler 内部的循环条件中检查 thread1.isAlive(),但 thread1 仍然即使 thread2 应该仍在运行时也会返回,即它在运行循环中的一次迭代后返回。顺便说一句,clientMesasgehandler 在其 run 方法中还包含一个无限循环。
      • 我认为你没有抓住重点。 Thread1 必须在您想要停止线程时从run() 方法返回。您需要在 Thread1 上调用 Thread#interrupt()。您需要重写 Thread1 的 run() 方法,以便它定期检查 Thread#isInterrupted() 是否返回 true,如果是则从 run() 方法返回。
      • 但是thread2不会被中断,它只是从它的run方法中返回,不再存活,这种情况下,我也想从thread1返回。
      • 在Thread2的构建过程中通过Thread1,在Thread1即将返回时让Thread2中断Thread1。要么,要么通过加入 Thread2 在主线程中控制它,然后立即中断 Thread1(如 Tim 的回答中所指出的那样)。
      猜你喜欢
      • 2023-03-29
      • 1970-01-01
      • 2015-09-29
      • 1970-01-01
      • 2017-04-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-29
      相关资源
      最近更新 更多