线程计算结果获取的正确方式,别再 Thread.sleep() 滥用了!
2023-09-22 15:49:54
介绍
在 Java 中,线程获取到运行结果有几种方式:
- 使用
Thread.join()
方法获取。这种方法可以等待线程执行完成,然后获取线程的执行结果。 - 使用
Thread.sleep()
方法获取。这种方法可以在指定的时间内等待线程执行完成,然后获取线程的执行结果。 - 使用
Future
类获取。这种方法可以异步地获取线程的执行结果。
Thread.sleep() 的问题
在 Java 中,使用 Thread.sleep()
方法来获取线程的执行结果是一种非常常见的方式。但是,这种方法存在一个很大的问题:它具有不可控性。也就是说,你无法保证线程在指定的时间内一定能够执行完成。如果线程在指定的时间内没有执行完成,那么 Thread.sleep()
方法就会导致你的程序卡死。
例如,下面的代码使用 Thread.sleep()
方法来获取线程的执行结果:
public class Test {
public static void main(String[] args) {
Thread thread = new Thread(() -> {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
thread.start();
try {
thread.join(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程执行结果:" + thread.getState());
}
}
这段代码中,我们创建了一个线程,并在线程中使用 Thread.sleep()
方法让线程休眠 5 秒。然后,我们在主线程中使用 thread.join(1000)
方法等待线程执行完成。但是,由于线程在 1 秒内无法执行完成,所以 thread.join(1000)
方法就会导致主线程卡死。
正确的获取线程执行结果的方式
为了避免使用 Thread.sleep()
方法来获取线程的执行结果,我们可以使用 Future
类。Future
类是一个异步计算的结果。它允许你在线程执行完成后获取线程的执行结果。
例如,下面的代码使用 Future
类来获取线程的执行结果:
public class Test {
public static void main(String[] args) {
ExecutorService executorService = Executors.newCachedThreadPool();
Future<String> future = executorService.submit(() -> {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "线程执行结果";
});
try {
System.out.println("线程执行结果:" + future.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
executorService.shutdown();
}
}
这段代码中,我们使用 Executors.newCachedThreadPool()
方法创建了一个线程池。然后,我们使用 ExecutorService.submit()
方法提交一个任务到线程池中执行。submit()
方法返回一个 Future
对象,我们可以使用 Future.get()
方法来获取任务的执行结果。
使用 Future
类来获取线程的执行结果,可以避免 Thread.sleep()
方法带来的不可控性问题。而且,Future
类还支持超时操作,我们可以指定等待线程执行完成的超时时间。如果线程在超时时间内没有执行完成,那么 Future.get()
方法就会抛出 TimeoutException
异常。
结语
在 Java 中,使用 Thread.sleep()
方法来获取线程的执行结果是一种非常常见的方式。但是,这种方法存在一个很大的问题:它具有不可控性。为了避免使用 Thread.sleep()
方法来获取线程的执行结果,我们可以使用 Future
类。Future
类是一个异步计算的结果。它允许你在线程执行完成后获取线程的执行结果。