并发动作和线程

时间:2013-03-13 14:32:24

标签: java multithreading

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

我也希望B等待A完成。

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

6 个答案:

答案 0 :(得分:2)

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

  

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

来自official tutorial的示例:

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

答案 1 :(得分: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();
  }
}

答案 2 :(得分:0)

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

干杯

答案 3 :(得分:0)

我不确定你的意思是“我希望B等待A完成”,我认为这意味着B需要在A之后运行。

您可以使用ExecutorService轻松完成此操作,在此示例中,它是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);
    }
}

除非你知道自己在做什么,否则我建议你不要弄乱Thread,这会导致危险的道路。使用提供的Executor,您不太可能遇到并发问题。

答案 4 :(得分: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在消息对象上发送通知。

答案 5 :(得分:0)

使用oracle javadocs here

中的Thread#join()