JSF Concurrency - 从托管bean启动线程以调用Service

时间:2018-02-20 12:32:34

标签: multithreading jsf concurrency

我有一个可以调用访问数据库的服务的ManagedBean。该服务具有@Service和@Transactional注释,并且因为它是一个具有在数据库中混乱的功能的服务,所以它显然在很多地方被调用。

在我的前端,在我的托管bean中,我想调用一个类似于作业,批处理的函数,它可能需要很长时间。这项工作可能需要1分钟,我不希望客户在前端等待很长时间,因为可能需要一个小时的工作。

我将发布一个我目前的代码示例(只考虑我在我的xhtml文件中有一个调用launchBatch()函数的按钮):

    @ManagedBean
    @RequestScoped
    public class JobLauncherController {

        @ManagedProperty("#{serviceController}")
        private ServiceController serviceController;

        public void launchBatch(String code) {
            switch (code) {
            case Constants.Batch.BATCH_1:
                Thread t1 = new Thread(new Runnable() {
                    public void run() {
                        serviceController.getBatchService().batch1();
                    }
                });
                t1.start();
                break;
            case Constants.Batch.BATCH_2:
                Thread t2 = new Thread(new Runnable() {
                    public void run() {
                        Date date = new Date();
                        String parameters = String
                                .valueOf(date.getHours() + ":" + date.getMinutes() + 
":" + date.getSeconds());
                        serviceController.getBatchService().batch2(parameters);
                    }
                });
                t2.start();
                break;
            case Constants.Batch.BATCH_3:
                Thread t3 = new Thread(new Runnable() {
                    public void run() {
                        serviceController.getBatchService().batch3();
                    }
                });
                t3.start();
                break;
            case Constants.Batch.BATCH_4:
                Thread t4 = new Thread(new Runnable() {
                    public void run() {
                        serviceController.getBatchService().batch4();
                    }
                });
                t4.start();
                break;
            default:
                break;
            }
            showGrowl();
        }

        public void showGrowl() {
            FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "",
 "Job launched sucessfully!");
            FacesContext.getCurrentInstance().addMessage("growlPanel", message);
        }

        public ServiceController getServiceController() {
            return serviceController;
        }

        public void setServiceController(ServiceController serviceController) {
            this.serviceController = serviceController;
        }


    }

我的服务(界面):

public interface AppBatchService {

    public void batch1();

    public void batch2(Object parameters);

    public void batch3();

    public void batch4();

}

实施

@Service
@Transactional
public class AppBatchServiceImpl implements AppBatchService {
//code to implementation goes here
}

所以这是成功启动一个线程,因为当我调试这个时,我已经让函数batchN休眠了一会儿,并且代码不断流向我的showGrowl()和我的showGrowl(),结束了代码流程成功地,问题出在前端,因为在我启动的线程运行时它没有完成按钮的操作。

在处理JSF / Primefaces以结束操作时,是否有一种特定的方法来启动线程,而不更改我的服务?我已经在函数中看到了@Stateless和@Asynchronous的解决方案,但是我无法改变这种结构。

0 个答案:

没有答案