返回

线程计算结果获取的正确方式,别再 Thread.sleep() 滥用了!

后端

介绍

在 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 类是一个异步计算的结果。它允许你在线程执行完成后获取线程的执行结果。