实现的方法有三种
-
主线程等待法
- 让主线程使用while循环不断的去查询成员变量, 直到成员变量符合条件为止
- 缺点
- 当需要等待的线程多起来之后, 代码就会臃肿
- 循环一次的时间不好确定
- 使用Thread的join方法阻塞当前线程, 直到子线程执行完毕
优点: 实现起来简单, 不用自己去确定等待时间了public class Demo01 implements Runnable { private static String value; @Override public void run() { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } value = "qweqwe"; } public static void main(String[] args) throws InterruptedException { Thread thread = new Thread(new Demo01()); thread.start(); thread.join(); System.out.println("value = " + value); } }
- 通过实现Callable接口 :使用这种方法时依旧有两种子方法来获取返回值
- 通过使用FutureTesk对象获取返回值
- FutureTask继承了Future接口
- FutureTask有两个get方法
- 无参的方法是, 当子线程执行完毕后获取其返回值
- 带参的方法是, 等待指定的时间来获取其返回值, 超时即放弃
- 代码
import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; public class Test01 { public static void main(String[] args) throws ExecutionException, InterruptedException { FutureTask task = new FutureTask<>(new MyCallable()); Thread thread = new Thread(task); thread.start(); if (!task.isDone()){ System.out.println("工作还没有完成!"); } System.out.println("完成了"+task.get()); System.out.println("111"); } }
- 通过线程池获取返回值
- 方法和FutureTask差不多
- 线程池的submit方法可以返回一个Future对象, 对象里面有get和isDone方法
- 通过使用FutureTesk对象获取返回值
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class Test02_ThreadPool {
public static void main(String[] args) {
ExecutorService threadPool = Executors.newCachedThreadPool();// 创建线程池
Future stringFuture = threadPool.submit(new MyCallable());// 提交线程任务, 返回的是一个Future
if (!stringFuture.isDone()) {
// 线程还没有执行完毕
System.out.println("任务还怎么完成~");
}
try {
System.out.println("任务完成了 " + stringFuture.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} finally {
threadPool.shutdown();// 关闭线程池
}
}
}
- Callable接口
- 这个接口只有一个方法call, 它其实和run方法差不多, 都是给线程设置任务
- 实现了Callable接口的类
import java.util.concurrent.Callable;
public class MyCallable implements Callable {
@Override
public String call() throws Exception {
System.out.println("开始工作");
Thread.sleep(2000);
System.out.println("工作完成");
return "hello";
}
}