HttpSession 内的同步是否可行? [英] Is synchronization within an HttpSession feasible?

查看:29
本文介绍了HttpSession 内的同步是否可行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新:问题后立即解决.

通常,同步是在 JVM 中序列化并行请求,例如

Usually, synchronization is serializing parallel requests within a JVM, e.g.

private static final Object LOCK = new Object();

public void doSomething() {
  ...
  synchronized(LOCK) {
    ...
  }
  ...
}

在查看 Web 应用程序时,JVM 全局"上的一些同步会被发现.范围可能成为性能瓶颈,同步仅在用户的HttpSession 会更有意义.

When looking at web applications, some synchronization on "JVM global" scope is maybe becoming a performance bottleneck and synchronization only within the scope of the user's HttpSession would make more sense.

以下代码是否可行?我怀疑在会话对象上同步是一个好主意,但听听您的想法会很有趣.

Is the following code a possibility? I doubt that synchronizing on the session object is a good idea but it would be interesting to hear your thoughts.

HttpSession session = getHttpServletRequest().getSession();
synchronized (session) {
  ...
}

关键问题:
是否保证会话对象对于处理来自同一用户的请求的所有线程同一个实例?

会话对象本身似乎并不总是相同,因为它取决于 servlet 容器(Tomcat、Glassfish 等)的实现,并且 getSession() 方法可能只返回一个包装器实例.

It seems that the session object itself is not always the same as it depends on the implementation of the servlet container (Tomcat, Glassfish, ...) and the getSession() method might return just a wrapper instance.

所以建议使用保存在会话中的自定义变量作为锁定对象.

这是我的代码提案,欢迎反馈:

Here is my code proposal, feedback is welcome:

Helper 类中的某处,例如MyHelper:

somewhere in a Helper Class, e.g. MyHelper:

private static final Object LOCK = new Object();

public static Object getSessionLock(HttpServletRequest request, String lockName) {
    if (lockName == null) lockName = "SESSION_LOCK";
    Object result = request.getSession().getAttribute(lockName);
    if (result == null) {
        // only if there is no session-lock object in the session we apply the global lock
        synchronized (LOCK) {
            // as it can be that another thread has updated the session-lock object in the meantime, we have to read it again from the session and create it only if it is not there yet!
            result = request.getSession().getAttribute(lockName);
            if (result == null) {
                result = new Object();
                request.getSession().setAttribute(lockName, result);
            }
        }
    }
    return result;
}

然后你就可以使用它了:

and then you can use it:

Object sessionLock = MyHelper.getSessionLock(getRequest(), null);
synchronized (sessionLock) {
  ...
}

对此解决方案有何评论?

Any comments on this solution?

推荐答案

这是我自己的解决方案:

会话对象本身似乎并不总是相同,因为它取决于 servlet 容器(Tomcat、Glassfish 等)的实现,并且 getSession() 方法可能只返回一个包装器实例.

Here is my own solution:

It seems that the session object itself is not always the same as it depends on the implementation of the servlet container (Tomcat, Glassfish, ...) and the getSession() method might return just a wrapper instance.

所以建议使用保存在会话中的自定义变量作为锁定对象.

这是我的代码提案,欢迎反馈:

Here is my code proposal, feedback is welcome:

Helper 类中的某处,例如MyHelper:

somewhere in a Helper Class, e.g. MyHelper:

private static final Object LOCK = new Object();

public static Object getSessionLock(HttpServletRequest request, String lockName) {
    if (lockName == null) lockName = "SESSION_LOCK";
    Object result = request.getSession().getAttribute(lockName);
    if (result == null) {
        // only if there is no session-lock object in the session we apply the global lock
        synchronized (LOCK) {
            // as it can be that another thread has updated the session-lock object in the meantime, we have to read it again from the session and create it only if it is not there yet!
            result = request.getSession().getAttribute(lockName);
            if (result == null) {
                result = new Object();
                request.getSession().setAttribute(lockName, result);
            }
        }
    }
    return result;
}

然后你就可以使用它了:

and then you can use it:

Object sessionLock = MyHelper.getSessionLock(getRequest(), null);
synchronized (sessionLock) {
  ...
}

对此解决方案有何评论?

Any comments on this solution?

这篇关于HttpSession 内的同步是否可行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆