我正在探索java.util.concurrent.* 计算正方形并等待使用Thread.sleep(5000),该程序按预期工作,但永远不会终止。eclipse中的红色方块是“ON”,我们通常用它来终止程序。你能帮忙理解程序为什么不在完成时终止? public static void main(String[] args) throws InterruptedException, ExecutionException { // TODO Auto-generated method stub try { SquareCalculator sqC = new SquareCalculator(); sqC.display(1); Future<Integer> result = sqC.calculate(5); while(!result.isDone()) { System.out.println("Waiting for the calculation"); Thread.sleep(1000); //result.cancel(true); } Integer square = result.get(); System.out.println(square); }catch(Exception e) { e.printStackTrace(); System.out.println("Calclulation was interrupted"); } }public class SquareCalculator { private ExecutorService ex = Executors.newSingleThreadExecutor(); public void display(int i) { // TODO Auto-generated method stub System.out.println(i); } public Future<Integer> calculate(Integer inp) { try { System.out.println("Before sending request"); Future<Integer> res = ex.submit(()->{ Thread.sleep(5000); return inp*inp; }); System.out.println("Request sent to caluclate and waiting for the result"); return res; }catch(Exception e) { System.out.println("calculation was interrupted"); return null; } //return ex.submit(()->squareing(inp)); }}OUTPUT1Before sending requestRequest sent to caluclate and waiting for the resultWaiting for the calculationWaiting for the calculationWaiting for the calculationWaiting for the calculationWaiting for the calculation25
3 回答
牧羊人nacy
TA贡献1862条经验 获得超7个赞
您需要重构代码并返回对象而不是Future。完成后,您还应该关闭执行程序。
import java.util.concurrent.ExecutionException;import java.util.concurrent.ExecutorService;import java.util.concurrent.
Executors;import java.util.concurrent.Future;public class SquareCalculator {
private ExecutorService ex = Executors.newSingleThreadExecutor();
public void display(int i) {
// TODO Auto-generated method stub
System.out.println(i);
}
public Integer calculate(Integer inp) {
Integer result;
try {
System.out.println("Before sending request");
Future<Integer> res = ex.submit(() -> {
Thread.sleep(5000);
return inp * inp;
});
System.out.println("Request sent to caluclate and waiting for the result");
result = res.get();
ex.shutdown();
return result;
} catch (Exception e) {
System.out.println("calculation was interrupted");
return null;
}
//return ex.submit(()->squareing(inp));
}
public static void main(String[] args) throws InterruptedException,
ExecutionException {
// TODO Auto-generated method stub
try {
SquareCalculator sqC = new SquareCalculator();
sqC.display(1);
Integer result = sqC.calculate(5);
System.out.println(result);
} catch (Exception e) {
e.printStackTrace();
System.out.println("Calclulation was interrupted");
}
}}
ITMISS
TA贡献1871条经验 获得超8个赞
我宁愿在Calculator类之外创建一个执行程序,并在构造函数中传递它。
这样,应用程序可以控制ExecutorService并在必要时将其关闭。
此外,如果您创建多个计算器实例,则所有实例都使用相同的执行程序服务,因此您可以控制并行运行的实例数。
计算方法中的阻塞有效,但是无法使用另一个线程进行异步计算。
public static void main(String[] args) {
// The executor is created by the application and then
// passed to the calculator
ExecutorService executor = Executors.newCachedThreadPool();
SquareCalculator calculator = new SquareCalculator(executor);
// calculate does not block
Future<Integer> calculate = calculator.calculate(12);
try {
while(true) {
try {
// wait a limited amount of time for the computation to complete
Integer result = calculate.get(1, TimeUnit.SECONDS);
System.out.println(result);
if(calculate.isDone()) {
// If the computation was either complete or cancelled just quit
break;
}
} catch (TimeoutException e) {
// We expect timeouts so we don't quit the loop for them
System.out.println("Waiting for result");
}
}
} catch (InterruptedException | ExecutionException e) {
// If there was an error or the computation was interrupted just quit.
e.printStackTrace();
}
// Shut down the executor so we do not leak pools.
executor.shutdown();
} public class SquareCalculator {
private ExecutorService ex;
public SquareCalculator(ExecutorService ex) {
super();
this.ex = ex;
}
public void display(int i) {
System.out.println(i);
}
public Future<Integer> calculate(Integer inp) {
try {
System.out.println("Before sending request");
Future<Integer> res = ex.submit(() -> {
Thread.sleep(5000);
return inp * inp;
});
System.out.println("Request sent to caluclate and waiting for the result");
return res;
} catch (Exception e) {
System.out.println("calculation was interrupted");
return null;
}
}
}
米脂
TA贡献1836条经验 获得超3个赞
如果要关闭VM,请致电System.exit()。是的,VM可以自动关闭而不调用该方法; 它会这样做,如果所有仍然“活”的线程都有'守护进程'标志(Thread类有一个.setDaemon方法用于此目的),但这是不好的代码风格。如果关闭点,则关闭(with System.exit)。
具体在这里,Executors.newSingleThreadExecutor()创建的线程; 未标记为守护程序线程。您可以通过向调用提供线程创建者来解决此问题。
但是,真的,不要。使用System.exit。
添加回答
举报
0/150
提交
取消
