如何向线程池的旧线程提供当前的vaadin会话?

时间:2015-08-11 10:41:07

标签: java vaadin threadpool vaadin7 vaadin-session

我在理解以下VaadinSession.getCurrent()

的引用时遇到 问题
  

获取当前使用的会话。当前会话是自动的   在处理对服务器的请求和线程启动时定义的   在定义当前会话时(参见   的InheritableThreadLocal)。在其他情况下(例如来自后台线程)   以其他方式启动),当前会话不是自动的   定义

具体以下几点对我来说很难理解,

  

...在主题中启动   在定义当前会话时(参见   的InheritableThreadLocal)。

这是什么意思?

我的理解是如果在定义新会话之前创建线程,或者在会话中创建线程,那么它将不会引用当前新创建的会话。

目前我有Thread Pool并且有些线程指的是现在关闭的旧会话然后我将面临在这些线程中使用会话的问题。

我正在使用spring vaadin,特别是@Async方法调用。

@Async
public static methodX() {
    //I have used session inside it
}

问题是,thread1已用于执行methodX,现在我已使用会话session1,在用户退出后,此session1将被关闭。

现在,当新用户登录到具有session2的系统并再次使用thread1执行此方法时,此方法仍然使用session1而不是session2当方法尝试从关闭 session1获取数据时会产生问题。

我的问题:

  • 为什么Vaadin无法提供或通知旧线程(属于旧(已关闭)会话的线程)关于新定义的Session
  • 为这些线程提供会话的 最佳 方式是什么?

2 个答案:

答案 0 :(得分:3)

这意味着如果您在单独的线程中处理数据,则不会有当前会话:

所以这段代码:

Runtime runtime = Runtime.getRuntime();                 
final Process process = runtime.exec(action);
new Thread() {
    public void run() {
        try {
            System.out.println(VaadinSession.getCurrent());
        } catch(IOException ioe) {
            ioe.printStackTrace();
        }
    }
}.start();
你的vaadin项目中的

会打印一个旧的会话,就是Thread启动时的会话。

修改

我认为Vaadin无法为旧线程提供新会话以避免数据损坏问题。我的意思是如果5个线程正在编辑同一个会话,那么你将遇到问题...

您的解决方案是为池中的每个线程提供Session,但我真的不知道如何实现这一点,Google到目前为止还没有给我答案。

编辑:另一种可能的解决方案

创建一个类,以静态方式使用HashMap<int, VaadinSession>存储每个会话(使用SessionListener)。

创建线程时,请为其提供需要使用的会话的ID(id是与您在HashMap中所需的会话相对应的键)。然后每次编辑,销毁会话时,只需在HashMap

中编辑它

由于此HashMap的静态行为,您可以随时从任何线程访问它,您唯一需要的是与线程中的会话相对应的int id。

答案 1 :(得分:0)

问题在于后台线程VaadinSession(不要与HttpSession混淆)不可用。在vaadin书中搜索了这个后,我得出了以下解决方案的结论。

要获得当前会话,我们有VaadinSession.getCurrent()UI.getCurrent().getSession()两者都会返回会话。

问题是在某些其他会话期间创建的旧线程无法访问当前会话,如引用中所述。只有@Async次调用才会出现这种情况。

@Async
public void method() {
   //get id from session
}

加载应用程序后,多个vaadin请求可以使用该方法,每次ThreadPool的线程执行任务。

Thread - 1 executed method - used session 1
session 1 closed
session 2 defined
Thread - 1 again used to execute method
Thread - 1 executed method - used session 1 instead of new defined session 2

现在,就我的每个vaadin请求而言,我们有了新的UI实例。但旧线程正在考虑的UI对于哪个会话已关闭已过时。

我已将UI实例外部传递给此异步方法,就像这样。

@Async
public void method(UI ui) {
   UI.setCurrent(ui);
   UI.getCurrent().getSession();//Now I have latest session
}

UI.setCurrent(UI ui)方法的文档中也说明了

  

应用程序开发人员也可以使用此方法来定义   正常请求处理之外的当前UI, 例如 在启动时   自定义后台线程。