谢谢以上两位。
我一个同事和我共同负责一个模块。我发现他写了那样的代码(共用实例变量),我叫他改,他不肯改。我跟他辩了半天,说不过他。之后我到www.apache.org网站上找develeper guide给他看,他也不看。希望大家支持我,知道的多签个名,好让他把代码改过来。
谢谢各位了!

解决方案 »

  1.   

    ACTION中每个方法都重新设置实例变量。也就是说,ACTION类里面有许多个方法,在每个方法执行之前都重新设置了实例变量(他跟我说一个方法不执行完成,两一个方法是不能执行的,我想问问大家这句话对吗?)。我想即使是在方法前面加同步标志也是会引起线程问题的,因为不同的用户执行不同的方法。同时,我还知道一个ACTION在WEB容器中只存在一个实例。
      

  2.   

    那肯定会引起线程安全问题的. 他的说法就是胡扯, 看来他不了解多线程啊, 并发操作中,两个方法会有可能交替执行的. 也就是说如果每个方法都会重新设置实例变量,那么,在一个方法运行期间如果切换到了另外一个方法,而另外一个方法重新设置了实例变量,那么线程切换回去的时候问题就冒出来了,简单的线程安全问题.  如果是每个方法都用了synchronized,那么就是线程安全的了, 就不会引起线程安全了. 因为每个方法的调用都会在当前对象上被同步, 而action实例只有一个.但是这样做会效率低下.
      

  3.   

    bellow is not my code!!!public class LoanAction
        extends DispatchAction {  private static LoanAnalysisDelegate lad = null;
      private static HttpSession session = null;
      private static SessionVo sessionvo = null;
      private static BigDecimal bigdecimal_parameter = new BigDecimal(0);
      private static String string_parameter = null;  private static int iBaseNum = 0;
      private static String sType = null;
      private static String sCourse = null;
      private static String sCondition = null;
      private static String sOrgid = null;  public ActionForward method1(ActionMapping mapping, ActionForm form,
                                           HttpServletRequest request,
                                           HttpServletResponse response) {
        try {
          lad = new LoanAnalysisDelegate();
          iBaseNum = Integer.parseInt(request.getParameter("iBaseNum"));
          sType = request.getParameter("sType");
          sCourse = request.getParameter("sCourse");
          sCondition = request.getParameter("sCondition");
          sOrgid = request.getParameter("sOrgid");
          if (iBaseNum != 0 && sType != null && sCourse != null && sCondition != null &&
              sOrgid != null) {
            bigdecimal_parameter = lad.f31_dkye(iBaseNum, sType, sCourse,
                                                sCondition, sOrgid);
          }
          request.setAttribute("bigdecimal_parameter", bigdecimal_parameter);
        }
        catch (SystemException sex) {
          sex.printStackTrace();
          request.setAttribute("errMessage", "获得科目数据字典失败!" + sex.getErrorNo());
        }
        catch (Exception ex) {
          ex.printStackTrace();
          request.setAttribute("errMessage", "远程访问服务器失败!");
        }
        finally {
          lad = null;
          sType = null;
          sCourse = null;
          sCondition = null;
          sOrgid = null;
        }
        return mapping.findForward("Return_some");
      }
      public ActionForward method2(ActionMapping mapping, ActionForm form,
                                         HttpServletRequest request,
                                         HttpServletResponse response) {
        try {
          lad = new LoanAnalysisDelegate();
          iBaseNum = Integer.parseInt(request.getParameter("iBaseNum"));
          sType = request.getParameter("sType");
          sCourse = request.getParameter("sCourse");
          sCondition = request.getParameter("sCondition");
          sOrgid = request.getParameter("sOrgid");
                if (iBaseNum != 0 && sType != null && sCourse != null && sCondition != null &&
              sOrgid != null) {
            bigdecimal_parameter = lad.f31_ff(iBaseNum, sType, sCourse, sCondition,
                                              sOrgid);
          }
          request.setAttribute("bigdecimal_parameter", bigdecimal_parameter);
        }
        catch (SystemException sex) {
          sex.printStackTrace();
          request.setAttribute("errMessage", "获得科目数据字典失败!" + sex.getErrorNo());
        }
        catch (Exception ex) {
          ex.printStackTrace();
          request.setAttribute("errMessage", "远程访问服务器失败!");
        }
        finally {
          lad = null;
          sType = null;
          sCourse = null;
          sCondition = null;
          sOrgid = null;
        }
        return mapping.findForward("Return_some");
      }
      public ActionForward method3(ActionMapping mapping, ActionForm form,
                                           HttpServletRequest request,
                                           HttpServletResponse response) {
        try {
          lad = new LoanAnalysisDelegate();
          iBaseNum = Integer.parseInt(request.getParameter("iBaseNum"));
          sType = request.getParameter("sType");
          sCourse = request.getParameter("sCourse");
          sCondition = request.getParameter("sCondition");
          sOrgid = request.getParameter("sOrgid");      if (iBaseNum != 0 && sType != null && sCourse != null && sCondition != null &&
              sOrgid != null) {
            bigdecimal_parameter = new BigDecimal(lad.f31_hwhs(iBaseNum, sType,
                sCourse, sCondition, sOrgid));
          }
          request.setAttribute("bigdecimal_parameter", bigdecimal_parameter);
        }
        catch (SystemException sex) {
          sex.printStackTrace();
          request.setAttribute("errMessage", "获得科目数据字典失败!" + sex.getErrorNo());
        }
        catch (Exception ex) {
          ex.printStackTrace();
          request.setAttribute("errMessage", "远程访问服务器失败!");
        }
        finally {
          lad = null;
          sType = null;
          sCourse = null;
          sCondition = null;
          sOrgid = null;
        }
        return mapping.findForward("Return_some");
      }
      
      这里还有很多方法,我只写前面的几个,方法名也换了....这个类太大了,写不下,大家知道意思就可以了。我敢说这样写一定会出问题
    }
      

  4.   

    服务器本身的处理请求机制是多线程
    每一个客户拥有不同的线程,在服务器内存中占据不同的地址空间,而request和session对象是与不同的线程互相绑定的,应该不会产生想象中的冲突
      

  5.   

    private static LoanAnalysisDelegate lad = null;
      private static HttpSession session = null;
      private static SessionVo sessionvo = null;
      private static BigDecimal bigdecimal_parameter = new BigDecimal(0);
      private static String string_parameter = null;  private static int iBaseNum = 0;
      private static String sType = null;
      private static String sCourse = null;
      private static String sCondition = null;
      private static String sOrgid = null;但是这块是共享的啊。我是说,这里会可能引起错误。比如A用户的线程把 iBaseNum 设为1, B用户的线程把它设为2
    ,两用户并发执行都使用这个iBaseNum,那么这个iBaseNum会不会混乱呢。我知道是request和session对象是不同的,但是上面的实例变量共享呢。
      

  6.   

    private static String sOrgid = null;你说的对,这个类的所有对象都会共享这个参数的内存空间,必须加以保护
      

  7.   

    一个ACTION只有一个类。因为ACTION也是SERVLET,在apache网站上有这样一句话。The controller servlet creates only one instance of your Action class, and uses this one instance to service all requests.
      

  8.   

    楼上的,你说错了。(这个类的所有对象都会共享这个参数的内存空间),一个Action只有一个实例。