Java/如何处理线程的返回值

Java/如何处理线程的返回值

如何给 run 方法传参

  • 构造函数传参
  • 成员变量传参
  • 回调函数传参

如何实现处理线程的返回值

循环等待法

让主线程循环等待,直到目标线程返回值为止。需要自己实现循环等待的逻辑,如果等待的变量比较多,代码就会显得臃肿。而且我们只能设置一个循环等待的间隔,比如循环判断值是否为空,如果不为空则继续等待 100 ms,如果在 100 ms 内有了值,我们无法更精确地去控制等待的时间。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class CycleWait implements Runnable {
private String value;

@Override
public void run() {
try {
//模拟子线程耗时操作
Thread.currentThread().sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
value = "we have data now";
}

public static void main(String[] args) {
CycleWait cycleWait = new CycleWait();
Thread t = new Thread(cycleWait);
t.start();
//判断 cycleWait.value 是否为空,如果为空,则循环等待100 ms,直到 cycleWait.value 不为空
while (cycleWait.value == null) {
try {
Thread.currentThread().sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("value: " + cycleWait.value);
}
}
## Thread.join() 使用 Thread 类的 join() 方法阻塞当前线程以等待子线程处理完毕。但是这种方法无法做到更精细的控制。这种方法比较简单,不展开讲解。

Callable

通过 Callable 接口实现。Callable 接口里面有 call() 方法,作用与 Runnable() 方法的作用类似,但不同的是:call() 有返回值,Callable 需要与 FutureTask 配合使用。 这种方法有两种实现:通过 FutureTask 获取或者线程池获取,下面分别介绍这两种方法: - 通过 FutureTask 获取: 首先定义一个 Callable 实现类,重写 call() 方法,返回一个 String。

1
2
3
4
5
6
7
8
9
10
11
public class MyCallable implements Callable<String> {
@Override
public String call() throws Exception {
String value="test";
System.out.println("Ready to work");
//模拟子线程耗时操作
Thread.currentThread().sleep(3000);
System.out.println("work done");
return value;
}
}
然后把 MyCallable 类的对象传给 FutureTask,再把 FutureTask 类的对象传给 Thread。最后通过task.get() 方法就可以阻塞,直到 Callable 的 call() 方法返回值。
1
2
3
4
5
6
7
public class FutureTaskDemo {
public static void main(String[] args) throws ExecutionException, InterruptedException {
FutureTask<String> task=new FutureTask<String>(new MyCallable());
new Thread(task).run();
System.out.println("task return: "+ task.get());
}
}
- 通过线程池获取返回值 与上面类似,不同的是通过线程池创建一个 Future 类的对象,通过 future.get() 方法接受 Callable 的返回值(上面的 FutureTask 也是实现了 Future 接口的类)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class ThreadPoolDemo {
public static void main(String[] args){
ExecutorService service = Executors.newCachedThreadPool();
//通过 Future 接受返回值
Future<String> future = service.submit(new MyCallable());
//调用 future.get(),会阻塞在这里,直到 Callable 返回了值
try {
System.out.println(future.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}finally {
//关闭线程池
service.shutdown();
}
}
}

评论