Callable 接口是一个线程吗?我不能 运行 在它工作时做任何事情

is Callable interface a thread? i can't run anything while it works

我已经为一个简单的 Maze 项目工作了一段时间,我已经到了需要将 Callable 接口用作线程的地步。在实施 运行 之后,我注意到虽然可调用 class 在后台运行,但我似乎无法在后台处理任何其他内容,例如输入。

我做了一个小项目来强调这个问题,看到当可调用的 class 工作 10 秒时,我不能同时接受任何输入。 这是代码:

主要class

public class Main {

    static ExecutorService service = null;
    static Future<String> task = null;

    public static void main(final String[] argv) throws IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        System.out.println("please enter a command");
        String string = in.readLine();
        while (!string.equals("exit")) {
            if (!string.equals("command")) {
                System.out.println("command not found");
            } else {
                service = Executors.newFixedThreadPool(1);
                task = service.submit(new Foo());

                try {
                    final String str;

                    // waits the 10 seconds for the Callable.call to finish.
                    str = task.get(); // this raises ExecutionException if
                                        // thread dies
                    System.out.println(str);
                    service.shutdownNow();
                } catch (final InterruptedException ex) {
                    ex.printStackTrace();
                } catch (final ExecutionException ex) {
                    ex.printStackTrace();
                }
            }
            string = in.readLine();

        }

        //
    }
}

可调用对象 class:

class Foo implements Callable<String> {
    @Override
    public String call() {
        try {
            // sleep for 10 seconds
            Thread.sleep(10 * 1000);
        } catch (final InterruptedException ex) {
            ex.printStackTrace();
        }

        return ("Hello, World!");
    }
}

Callable 本身不做任何事情。它只是一个约定接口。要使可调用异步,您需要在执行程序中 运行 它。例如,参见 https://blogs.oracle.com/CoreJavaTechTips/entry/get_netbeans_6

https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html#submit(java.util.concurrent.Callable)

If you would like to immediately block waiting for a task, you can use constructions of the form result = exec.submit(aCallable).get();

这正是你在做的(阻塞主线程等待任务)

问题是str = task.get();

根据 Future#get() 的 JavaDoc (https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html#get%28%29):

Waits if necessary for the computation to complete, and then retrieves its result.

如果您想要 Callable 的结果,您必须等到它完成。

i've noticed that while the callable class runs in the background, i cant seem to work anything else on the background

...讨论,...问题解释...

it seems pointless to use this interface now.

我真的不知道你想做什么,但 ExecutorServiceCallable 的全部意义在于在后台执行任务。

但是"in the background"是什么意思呢?这意味着,当新线程停止执行某些任务时,提交任务的线程可以做其他事情

看起来像这样:

final ExecutorService executorService = Executors.newFixedThreadPool(NUM_THREADS);

ReturnType doSomethingInTheBackground() {

    // create the task object
    Callable<ReturnType> task = () -> doSomething();

    // submit the task object
    Future<ReturnType> future = executorService.submit(task);

    doSomethingElse();

    // wait for the result.
    return future.get();
}

private ReturnType doSomething() { ... }

private void doSomethingElse() { ... }

doSomethingElse() 的呼吁让这一切都变得值得。如果调用线程除了等待结果(即调用 future.get())之外没有其他事情可做,那么你是对的:使用多个线程没有意义。调用线程自己完成任务会更简单。