我想同时执行两个名为A和B的方法。
我也希望B等待A完成。
如何通过在Java中实现线程来实现这样的结果?
答案 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()