为了账号安全,请及时绑定邮箱和手机立即绑定

虽然程序在使用线程时成功执行,但程序的执行并未结束

虽然程序在使用线程时成功执行,但程序的执行并未结束

jeck猫 2019-04-17 18:15:12
我正在探索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");
        }
    }}


查看完整回答
反对 回复 2019-05-15
?
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;
            }
        }
    }


查看完整回答
反对 回复 2019-05-15
?
米脂

TA贡献1836条经验 获得超3个赞

如果要关闭VM,请致电System.exit()。是的,VM可以自动关闭而不调用该方法; 它会这样做,如果所有仍然“活”的线程都有'守护进程'标志(Thread类有一个.setDaemon方法用于此目的),但这是不好的代码风格。如果关闭点,则关闭(with System.exit)。

具体在这里,Executors.newSingleThreadExecutor()创建的线程; 未标记为守护程序线程。您可以通过向调用提供线程创建者来解决此问题。

但是,真的,不要。使用System.exit


查看完整回答
反对 回复 2019-05-15
  • 3 回答
  • 0 关注
  • 575 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号