以前の仕事では主に業務コードを書いていましたが、スレッドを使うことはほとんどなく、スレッド実行後の戻り値の取得については考えていませんでしたが、スレッド内の run() メソッドには戻り値がありません。では、スレッドの実行後に対応する値を取得したい場合はどうすればよいでしょうか? 最近の研究をもとにまとめます。スレッドから値を返す方法はいくつかあります。
目次
4. CallableインターフェイスとFutureTaskを使用する
1. 値を直接取得する
デモを通してデモをしてみよう
public class MyThreadReturn implements Runnable {
/** 模拟线程执行完毕后主程序要获取的值*/
private String returnValue;
@Override
public void run() {
System.out.println("线程执行......");
/** 模拟IO*/
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程执行完毕......");
returnValue = "hello world!!!";
}
public String getReturnValue(){
return returnValue;
}
public static void main(String[] args) {
MyThreadReturn myThreadReturn = new MyThreadReturn();
Thread thread = new Thread(myThreadReturn);
thread.start();
System.out.println(myThreadReturn.getReturnValue());
}
}
上記のコードは MyThreadReturn スレッドで実行するのに 5 秒かかるため、メイン スレッドで returnValue を正常に取得できません。
null
线程执行.....
コードを次のように変更します
2. ループ判定
この手法の本質は、ビジネスロジックを自分で制御することです
public static void main(String[] args) throws InterruptedException {
MyThreadReturn myThreadReturn = new MyThreadReturn();
Thread thread = new Thread(myThreadReturn);
thread.start();
/** 通过while循环判断*/
while (myThreadReturn.getReturnValue() == null){
Thread.sleep(1000);
}
System.out.println(myThreadReturn.getReturnValue());
}
3.結合を使用する
join メソッドを使用すると、メインスレッドの実行後にサブスレッドが実行されるため、ループで判断するのと実質的に同じになります。
public static void main(String[] args) throws InterruptedException {
MyThreadReturn myThreadReturn = new MyThreadReturn();
Thread thread = new Thread(myThreadReturn);
thread.start();
/** 使用join*/
thread.join();
System.out.println(myThreadReturn.getReturnValue());
}
4. CallableインターフェイスとFutureTaskを使用する
コードは以下の通りで、FutureTaskのget()メソッドで戻り値を取得します。
public class MyCallable implements Callable<String> {
@Override
public String call() throws Exception {
System.out.println("线程执行......");
Thread.sleep(5000);
System.out.println("线程执行完毕......");
return "hello world!!!";
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
FutureTask<String> futureTask = new FutureTask<>(new MyCallable());
/***
* futureTask 实现了 Runnable接口
* 所以新建线程的时候可以传入futureTask
* FutureTask重写的run方法中实际是调用了Callable接口在call()方法
* 所以执行线程的时候回执行call方法的内容
*/
Thread thread = new Thread(futureTask);
thread.start();
String value = futureTask.get();
System.out.println(value);
}
}
5. スレッドプールを使用する
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService executorService = Executors.newCachedThreadPool();
Future<String> submit = executorService.submit(new MyCallable());
System.out.println(submit.get());
}
上記のコードの戻り値は、
线程执行......
线程执行完毕......
hello world!!!