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
29public 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);
}
}
Callable
通过 Callable 接口实现。Callable 接口里面有 call() 方法,作用与 Runnable() 方法的作用类似,但不同的是:call() 有返回值,Callable 需要与 FutureTask 配合使用。 这种方法有两种实现:通过 FutureTask 获取或者线程池获取,下面分别介绍这两种方法: - 通过 FutureTask 获取: 首先定义一个 Callable 实现类,重写 call() 方法,返回一个 String。 1
2
3
4
5
6
7
8
9
10
11public 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;
}
}1
2
3
4
5
6
7public 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());
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18public 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();
}
}
}