Java Future.isDone返回true,即使它不应该停止程序进度

时间:2015-06-05 19:07:52

标签: java future executorservice

我有一个SwingWorker,它启动一个LinkedBlockingQueue,将它传递给另一个方法(PortalDriver,下面),然后在doInBackground()方法中读取它。 LinkedBlockingQueue保存自定义对象的期货(并且它肯定是正确填充的)。作为一个检查,我正在创建的对象(通过ExecutorService)在构造函数的末尾有一个println(this),因此我知道它们何时被创建。

问题是,通过println()调用(在doInBackground和构造函数中),在doInBackground中的while循环中进行了多次成功迭代后,行

var arr = [{a:1,b:2},{a:3,b:4},{a:5,b:6},{a:7,b:8},{a:9,b:10}];

function getIt(num){
  return arr.filter(function(item){
    return item.a === num;
  }).pop().b
}

alert(getIt(5));

打印为true,即使构造函数没有打印它已经创建(这只是通过计数清楚)。即使创建了其余的对象,while循环也会永久阻塞。

System.out.println("future.isDone before get(): " + futureListing.isDone());

刚刚完成,这里是getScheduleElements,它填满了LinkedBlockingQueue:

private class ReadSchedWorker extends SwingWorker<Void, Listing> {
    private ChromeOptions options = new ChromeOptions();
    private WebDriver driver;
    private LinkedBlockingQueue<Future<Listing>> listingQueue;
    private LoginFactory loginFactory;
    private int year;
    private int month;
    private int day;

    public ReadSchedWorker(Login mediasiteLogin, Login tmsLogin,
                           int year, int month, int day) {
        System.setProperty("webdriver.chrome.driver", "\\\\private\\Home\\Desktop\\chromedriver.exe");
        listingQueue = new LinkedBlockingQueue<>();
        loginFactory = new LoginFactory(mediasiteLogin, tmsLogin);
        this.year = year;
        this.month = month;
        this.day = day;
    }

    @Override
    protected Void doInBackground() throws Exception {
        this.options.addArguments("--disable-extensions");
        driver = new ChromeDriver(options);

        String portalUsername = loginFactory.getPortalUsername();
        String portalPassword = loginFactory.getPortalPassword();
        PortalDriver portalDriver = new PortalDriver(driver, listingQueue);
        portalDriver.getScheduleElements(portalUsername, portalPassword, year, month, day);

        while (!listingQueue.isEmpty()) {
            System.out.println("beginning");
            Future<Listing> futureListing = listingQueue.take();
            System.out.println("future.isDone before get(): " + futureListing.isDone());
            Listing listing = futureListing.get();
            System.out.println("future.isDone after get(): " + futureListing.isDone());
            System.out.println("before publish");
            publish(listing);
            System.out.println("after publish");
        }
        return null;
    }

    @Override
    protected void process(List<Listing> listings) {
        for (Listing listingItem : listings) {
            listingListModel.addElement(listingItem);
        }
    }
}

编辑: 我的意思的一个例子(未来未完成,但通过doInBackground()中的println()报告它是:

public void getScheduleElements(String username, String password, int year, int month, int day) {
    driver.get("https://rxsecure.umaryland.edu/apps/schedules/view/?type=search&searchtype=resource&id=100&start=" +
            year + "-" + month + "-" + day + "&scope=week");
    PortalLoginPage loginPage = PageFactory.initElements(driver, PortalLoginPage.class);
    PortalScheduleEventsWeekPage scheduleEventsWeekPage = loginPage.login(username, password);
    webElementsQueue = scheduleEventsWeekPage.initEventsQueue();

    // doesn't need to be a queue...
    // this is sequential....
    // could do a parallel stream
    while (webElementsQueue.peek() != null) {
        Callable<Listing> callable = new PortalListingCallable(webElementsQueue.poll());
        Future<Listing> future = executor.submit(callable);
        listingQueue.offer(future);
    }

    executor.shutdown();
}

1 个答案:

答案 0 :(得分:4)

  

打印为true,即使构造函数尚未打印已创建

您很可能会收到一个您没有看到的异常或错误。你必须调用Future.get()才能看到它。

与此同时,我建议你改变

Future<Listing> future = executor.submit(callable);

Future<Listing> future = executor.submit(new Callable<Listing>() {
    public Listing call() throws Throwable {
        try {
            return callable.call();
        } catch (Throwable t) {
            t.printStackTrace();
            throw t;
        }
    }
});