我正在探索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
提交
取消