我正在玩Callable和Future,偶然发现了一个问题。
即使IDE允许运行5秒钟,这段代码永远不会终止并超时,并且代码不需要超过3秒(它会超出时间限制错误):https://ideone.com/NcL0YV
/* package whatever; // don't place package name! */
import java.util.*;
import java.util.concurrent.*;
import java.lang.*;
import java.io.*;
/* Name of the class has to be "Main" only if the class is public. */
class Ideone
{
public static void main (String[] args) throws java.lang.Exception
{
Ideone obj = new Ideone();
Future<Integer> res = obj.doCallable();
System.out.println(res.get());
}
public Future<Integer> calculate(Integer input) {
ExecutorService executor = Executors.newFixedThreadPool(1);
return executor.submit(() -> {
long start = System.currentTimeMillis();
Thread.sleep(2000);
System.out.println("Sleep time in ms = "+(System.currentTimeMillis()-start));
return input * input;
});
}
public Future<Integer> doCallable() {
int value = 99;
try {
Callable<Future> callable = () -> calculate(value);
Future<Integer> future = callable.call();
return future;
} catch (final Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}
这是一段类似的代码终止,因为我添加了&#34; System.exit(0)&#34; (这不可取):https://ideone.com/HDvl7y
/* package whatever; // don't place package name! */
import java.util.*;
import java.util.concurrent.*;
import java.lang.*;
import java.io.*;
/* Name of the class has to be "Main" only if the class is public. */
class Ideone
{
public static void main (String[] args) throws java.lang.Exception
{
Ideone obj = new Ideone();
Future<Integer> res = obj.doCallable();
System.out.println(res.get());
System.exit(0);
}
public Future<Integer> calculate(Integer input) {
ExecutorService executor = Executors.newFixedThreadPool(1);
return executor.submit(() -> {
long start = System.currentTimeMillis();
Thread.sleep(2000);
System.out.println("Sleep time in ms = "+(System.currentTimeMillis()-start));
return input * input;
});
}
public Future<Integer> doCallable() {
int value = 99;
try {
Callable<Future> callable = () -> calculate(value);
Future<Integer> future = callable.call();
return future;
} catch (final Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}
请帮助我理解为什么我们需要System.exit(0)或shutdown(),即使可调用任务完成(future.get()调用是阻塞调用)。
修改 由于下面的代码片段,我做了以上所有解决我的应用程序中不断增加的线程的主要问题。我不确定如何在一定的超时后自动完成这个未来而不涉及主线程(立即退出)。
@Override
public void publish(@NonNull final String message,
@NonNull final String topicArn) throws PublishingException {
if (!publishAsync(message, topicArn)) {
throw new PublishingException("Publish attempt failed for the message:"
+ message);
}
}
private boolean publishAsync(final String message,
final String topicArn) {
Callable<Future> publishCallable = () -> snsClient.publishAsync(topicArn, message);
try {
Future<PublishResult> result = publishCallable.call();
log.debug("Asynchronously published message {} to SNS topic {}.", message, topicArn);
return !result.isDone() || result.get().getMessageId() != null;
} catch (final Exception e) {
return false;
}
}
答案 0 :(得分:0)
空隙shutdown()方法
启动有序关闭,其中先前提交的任务已执行,但不会接受任何新任务。如果已经关闭,调用没有额外的效果。
此方法不会等待先前提交的任务完成执行。使用awaitTermination来做到这一点。