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。
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.
我真的不知道你想做什么,但 ExecutorService
和 Callable
的全部意义在于在后台执行任务。
但是"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()
)之外没有其他事情可做,那么你是对的:使用多个线程没有意义。调用线程自己完成任务会更简单。
我已经为一个简单的 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。
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.
我真的不知道你想做什么,但 ExecutorService
和 Callable
的全部意义在于在后台执行任务。
但是"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()
)之外没有其他事情可做,那么你是对的:使用多个线程没有意义。调用线程自己完成任务会更简单。