0

我想同时执行两个方法,名为 A 和 B。

我也希望 B 等待 A 完成。

如何通过在 Java 中实现线程来实现这样的结果?

4

6 回答 6

2

使用Thread#join()。在要等待死亡的线程对象上调用它。

join 方法允许一个线程等待另一个线程完成。

来自官方教程的示例:

public class SimpleThreads {

    // Display a message, preceded by
    // the name of the current thread
    static void threadMessage(String message) {
        String threadName =
            Thread.currentThread().getName();
        System.out.format("%s: %s%n",
                          threadName,
                          message);
    }

    private static class MessageLoop
        implements Runnable {
        public void run() {
            String importantInfo[] = {
                "Mares eat oats",
                "Does eat oats",
                "Little lambs eat ivy",
                "A kid will eat ivy too"
            };
            try {
                for (int i = 0;
                     i < importantInfo.length;
                     i++) {
                    // Pause for 4 seconds
                    Thread.sleep(4000);
                    // Print a message
                    threadMessage(importantInfo[i]);
                }
            } catch (InterruptedException e) {
                threadMessage("I wasn't done!");
            }
        }
    }

    public static void main(String args[])
        throws InterruptedException {

        // Delay, in milliseconds before
        // we interrupt MessageLoop
        // thread (default one hour).
        long patience = 1000 * 60 * 60;

        // If command line argument
        // present, gives patience
        // in seconds.
        if (args.length > 0) {
            try {
                patience = Long.parseLong(args[0]) * 1000;
            } catch (NumberFormatException e) {
                System.err.println("Argument must be an integer.");
                System.exit(1);
            }
        }

        threadMessage("Starting MessageLoop thread");
        long startTime = System.currentTimeMillis();
        Thread t = new Thread(new MessageLoop());
        t.start();

        threadMessage("Waiting for MessageLoop thread to finish");
        // loop until MessageLoop
        // thread exits
        while (t.isAlive()) {
            threadMessage("Still waiting...");
            // Wait maximum of 1 second
            // for MessageLoop thread
            // to finish.
            t.join(1000);
            if (((System.currentTimeMillis() - startTime) > patience)
                  && t.isAlive()) {
                threadMessage("Tired of waiting!");
                t.interrupt();
                // Shouldn't be long now
                // -- wait indefinitely
                t.join();
            }
        }
        threadMessage("Finally!");
    }
}
于 2013-03-13T14:35:03.320 回答
0

这是您应该能够开始使用的示例双线程代码片段:

public class TwoThreads {
  public static void main(String args[]) throws InterruptedException {
    System.out.println("TwoThreads:Test");
    new TwoThreads().test();
  }
  // The end of the list.
  private static final Integer End = -1;

  static class Producer implements Runnable {
    final Queue<Integer> queue;

    public Producer(Queue<Integer> queue) {
      this.queue = queue;
    }

    @Override
    public void run() {
      try {
        for (int i = 0; i < 1000; i++) {
          queue.add(i);
          Thread.sleep(1);
        }
        // Finish the queue.
        queue.add(End);
      } catch (InterruptedException ex) {
        // Just exit.
      }
    }
  }

  static class Consumer implements Runnable {
    final Queue<Integer> queue;

    public Consumer(Queue<Integer> queue) {
      this.queue = queue;
    }

    @Override
    public void run() {
      boolean ended = false;
      while (!ended) {
        Integer i = queue.poll();
        if (i != null) {
          ended = i == End;
          System.out.println(i);
        }
      }
    }
  }

  public void test() throws InterruptedException {
    Queue queue = new LinkedBlockingQueue();
    Thread pt = new Thread(new Producer(queue));
    Thread ct = new Thread(new Consumer(queue));
    // Start it all going.
    pt.start();
    ct.start();
    // Wait for it to finish.
    pt.join();
    ct.join();
  }
}
于 2013-03-13T14:35:53.633 回答
0

你需要的是FutureJava类。访问异步调用的方法的结果非常简单。
检查 Javadocs http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/Future.html以获得更好的解释。

干杯

于 2013-03-13T14:39:12.577 回答
0

我不确定您所说的“我希望 B 等待 A 完成”是什么意思,我认为它的意思是 B 需要在 A 之后运行。

您可以使用 轻松完成此操作ExecutorService,在此示例中它是 a singleThreadExecutorService,因此可以保证在 A 之后运行 B。

唯一的问题是,如果 A 出现问题退出,它将不会被拾取,因此您可能希望分配一个看门狗线程来使用该Future.get方法获取 A 的状态,然后在 A 成功时调度 B。

public static Object a() {
    return new Object();

}

public static Object b() {
    return new Object();
}

public static class CallA implements Callable<Object> {

    public Object call() throws Exception {
        return a();
    }
}

public static class CallB implements Callable<Object> {

    public Object call() throws Exception {
        return b();
    }
}

public static void main(String[] args) {
    final ExecutorService executorService = Executors.newSingleThreadExecutor();
    final Future<Object> aFuture = executorService.submit(new CallA());
    final Future<Object> bFuture = executorService.submit(new CallB());
    try {
        aFuture.get();
        bFuture.get();
    } catch (InterruptedException ex) {
        Thread.currentThread().interrupt();
    } catch (ExecutionException ex) {
        throw new RuntimeException(ex);
    }
}

我建议你不要弄乱Threads 除非你知道你在做什么 - 它可能会导致危险的道路。使用Executor提供的 s,您遇到并发问题的可能性要小得多。

于 2013-03-13T14:48:50.377 回答
0

在公共对象上使用等待和通知方法

Class ClassA implements runnable{
    Message messageA;
    public ClassA(Message messageA){
        this.messageA = messageA;
    }
    public void run(){
                    //code here
            messageA.notify();

    }
}
Class ClassB implements runnable{
    Message messageA;
    public ClassB(Message messageA){
        this.messageA = messageA;

    }
    public void run(){
            messageA.wait();
            //code here
    }
}

public static void main(){
     Message message = new Message();// a simplest object here can be String
     //ctreate thread of ClassA(message);
    //create thread of classB(message);
}

线程 B 将等待,直到线程 A 发送消息对象的通知。

于 2013-03-13T14:57:46.230 回答
0

在此处使用 oracle javadocs 中的 Thread#join()

于 2013-03-13T14:58:16.157 回答