使用信号量顺序运行swingworkers

时间:2013-01-08 10:12:07

标签: semaphore swingworker jtabbedpane

我有一个带有JTabbedpane的面板,在每个选项卡中都可以设置参数来执行查询。当一个查询忙于从数据库中检索其数据时,您可以打开一个新选项卡来设置新参数。为避免数据库过载,一次只能执行一个查询。但是当您单击执行时,程序必须记住以正确的顺序执行哪些查询。在执行期间,会显示加载程序图标,并且GUI可能不会被冻结,因为有一个停止按钮,您可以单击以停止执行。
我使用swingworker来避免GUI在执行查询时阻塞,并且工作正常。但是现在我想阻止下一个查询在上一个查询完成之前启动。在整个面板中常见的模型中,我初始化了一个信号量:private final Semaphore semaphore = new Semaphore(1, true);

这是启动swingworker的代码(我添加了println命令来查看哪个启动,停止或完成)

private void doStoredQuery() {
        try {
            semaphore.acquire();
            System.out.println(queryName + "started");
            worker.execute();
        } catch (InterruptedException e) {
           throw new RuntimeException(e);
        }
    }

这是我的swingworker(从主类的构造函数调用initializeWorker()):

private SwingWorker<StoredQueryDataModel, Integer> initializeWorker() {
    worker = new SwingWorker<StoredQueryDataModel, Integer>() {
        @Override
        protected StoredQueryDataModel doInBackground() throws Exception {
            try {
                StoredQueryDataModel dataModel = null;
                publish(0);
                try {
                    dataModel = new StoredQueryDataModel(queryRunner, ldbName, queryName, params);
                } catch (S9SQLException e) {
                    // 
                } catch (Throwable e) {
                    showErrorMessage(e);
                }
                return dataModel;
            }
            finally {
                semaphore.release();
                System.out.println(queryName + "finished");
            }
        }

        @Override
        protected void process(List<Integer> chunks) {
            //ignore chunks, just reload loader icon
            panel.repaint();
        }

        @Override
        protected void done() {
            String error;
            try {
                result = get();
                error = null;
            } catch (Exception e) {
                error = e.getMessage();
            }

            if(result == null) {
                semaphore.release();
                System.out.println(queryName + " stopped");
            }

            if(error == null) {
                // process result
            }
            else {
                showErrorMessage(new Throwable(error));
            }
        }

    };
    return worker;
}

我已尝试将获取和释放放在代码中的其他位置,但似乎没有任何效果。我是Swingworker和sempahores的机器人很新......有人可以帮忙吗?

1 个答案:

答案 0 :(得分:0)

我发现了问题:信号量必须是一个静态变量。在我的代码中,有与tab一样多的信号量,这导致它们同时运行而不是顺序运行。