0

A と B という名前の 2 つのメソッドを同時に実行したいと考えています。

また、A が終了するまで B を待ちたいと思います。

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

これは、開始できるはずの2スレッドコードフラグメントのサンプルです。

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

共通オブジェクトでwaitメソッドとnotifyメソッドを使用する

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

threadBは、スレッドAが通知メッセージオブジェクトを送信するまで待機します。

于 2013-03-13T14:57:46.230 に答える
0

ここでoraclejavadocsのThread#join()を使用します

于 2013-03-13T14:58:16.157 に答える
0

必要なのはFutureJava のクラスです。非同期的に呼び出されたメソッドの結果へのアクセスが非常に簡単になります。より良い説明については
、Javadoc http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/Future.htmlを確認してください。

乾杯

于 2013-03-13T14:39:12.577 に答える
0

「A が終了するまで B に待ってもらいたい」という言葉の意味がよくわかりませんが、B が A の後に実行する必要があるという意味だと解釈しました。

これは を使用して簡単に実行できますExecutorService。この例では であるsingleThreadExecutorServiceため、A の後に B が実行されることが保証されています。

唯一の問題は、A が問題で終了した場合にピックアップされないことです。そのため、メソッドを使用して A のステータスをピックアップするウォッチドッグ スレッドを割り当て、Future.getA が成功した場合に 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);
    }
}

自分が何をしているのかを理解していない限り、s を台無しにしないことをお勧めしますThread。危険な道につながる可能性があります。提供されているを使用すると、Executor同時実行の問題が発生する可能性が大幅に低くなります。

于 2013-03-13T14:48:50.377 に答える