Using threads with return values in Java

When creating multi-threaded programs, we often implement the Runnable interface. Runnable has no return value. To get the return value, Java5 provides a new interface Callable, which can get the return value in the thread, but when getting the return value of the thread , It should be noted that our method is asynchronous. When obtaining the return value, the thread task does not necessarily have a return value. Therefore, it is necessary to judge whether the thread ends before it can get the value.

test code

package com.wuwii.test;

import java.util.concurrent.*;

/**
 * @author Zhang Kai
 * @version 1.0
 * @since <pre>2017/10/31 11:17</pre>
 */
public class Test {

    private static final Integer SLEEP_MILLS = 3000;

    private static final Integer RUN_SLEEP_MILLS = 1000;

    private int afterSeconds = SLEEP_MILLS / RUN_SLEEP_MILLS;

    // 线程池(根据机器的核心数)
    private final ExecutorService fixedThreadPool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());

    private void testCallable() throws InterruptedException {
        Future<String> future = null;
        try {
            /**
             * 在创建多线程程序的时候,我们常实现Runnable接口,Runnable没有返回值,要想获得返回值,Java5提供了一个新的接口Callable
             *
             * Callable需要实现的是call()方法,而不是run()方法,返回值的类型有Callable的类型参数指定,
             * Callable只能由ExecutorService.submit() 执行,正常结束后将返回一个future对象。
             */
            future = fixedThreadPool.submit(() -> {
                Thread.sleep(SLEEP_MILLS);
                return "The thread returns value.";
            });
        } catch (Exception e) {
            e.printStackTrace();
        }

        if (future == null) return;

        for (;;) {
            /**
             * 获得future对象之前可以使用isDone()方法检测future是否完成,完成后可以调用get()方法获得future的值,
             * 如果直接调用get()方法,get()方法将阻塞到线程结束,很浪费。
             */
            if (future.isDone()) {
                try {
                    System.out.println(future.get());
                    break;
                } catch (InterruptedException | ExecutionException e) {
                    e.printStackTrace();
                }
            } else {
                System.out.println("After " + afterSeconds-- + " seconds,get the future returns value.");
                Thread.sleep(1000);
            }
        }
    }
    public static void main(String[] args) throws InterruptedException {
        new Test().testCallable();
    }
}

operation result:

After 3 seconds,get the future returns value.
After 2 seconds,get the future returns value.
After 1 seconds,get the future returns value.
The thread returns value.

Summarize:

  1. The thread that needs to return a value uses the Callable interface and implements the call method;
  2. Before obtaining the future object, you can use the isDone() method to detect whether the future is completed. After completion, you can call the get() method to obtain the value of the future. If you directly call the get() method, the get() method will block until the thread ends.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325206205&siteId=291194637