我正在尝试返回stats
对象。
但我得到了
从内部类引用的局部变量必须是final或 有效的最终
stats = statistics;
上的如何返回对象,但确保运行.close();
?
public static Statistics getStatistics(String environmentName) {
Container container = getContainer(environmentName);
Statistics stats = new Statistics();
try {
dockerClient().statsCmd(container.getId()).exec(new ResultCallback<Statistics>() {
@Override
public void onStart(Closeable closeable) {
}
@Override
public void onNext(Statistics statistics) {
stats = statistics;
}
@Override
public void onError(Throwable throwable) {
}
@Override
public void onComplete() {
}
@Override
public void close() throws IOException {
}
}).close();
} catch (IOException e) {
e.printStackTrace();
}
return stats;
}
答案 0 :(得分:0)
你正在创造一个无法形成的内部阶级:
new ResultCallback<Statistics>() { @Override public void onStart(Closeable closeable) { } @Override public void onNext(Statistics statistics) { stats = statistics; } @Override public void onError(Throwable throwable) { } @Override public void onComplete() { } @Override public void close() throws IOException { } }).close();
问题是你在方法中定义了不必要的统计数据,因为你在匿名内部类@Override public void onNext(Statistics statistics) { stats = statistics; }
中再次定义它
相反,尝试直接在类中声明变量并初始化为null。内部函数只在匿名类中重新定义它。
答案 1 :(得分:0)
您想要致电getStatistics
并立即使用生成的统计信息。这称为 synchrone 用法。
但实际上只有异步才会被回调通知统计数据最终到达。
所以改变:
f(String env) {
Statistics stats = getStatistics(env);
g(stats);
}
到
f(String env) {
retrievStatistics(env);
}
public static void retrieveStatistics(String environmentName) {
Container container = getContainer(environmentName);
stats = null;
try {
dockerClient().statsCmd(container.getId()).exec(new ResultCallback<Statistics>() {
Statistics stats;
@Override
public void onNext(Statistics statistics) {
g(statistics);
stats = statistics; // Alternative when using onComplete instead.
}
@Override public void onStart(Closeable closeable) {}
@Override public void onError(Throwable throwable) { }
@Override public void onComplete() {
g(stats); // Or this
}
@Override public void close() throws IOException { }
}).close();
} catch (IOException e) {
e.printStackTrace();
}
}
像你一样忙碌的等待循环是不理想的。
答案 2 :(得分:0)
您可以尝试使用java.util.concurrent.CompletableFuture(java 8)。 在这种情况下:
public static Statistics getStatistics(String environmentName) {
Container container = null;
CompletableFuture<Statistics> future = new CompletableFuture<>();
try {
dockerClient().statsCmd(container.getId()).exec(new ResultCallback<Statistics>() {
@Override
public void onStart(Closeable closeable) {
}
@Override
public void onNext(Statistics statistics) {
if (!future.isDone()) {
future.complete(statistics);
}
}
@Override
public void onError(Throwable throwable) {
future.completeExceptionally(throwable);
}
@Override
public void onComplete() {
if (!future.isDone()) {
future.complete(null);
}
}
@Override
public void close() throws IOException {
}
}).close();
} catch (IOException e) {
e.printStackTrace();
}
try {
// wait until statistics resolved
return future.get();
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
}
}
或者,如果exec代码是同步的,则可以使用AtomicReference作为临时容器。该方法类似于上面的CompletableFuture示例,但开销较小