在Web应用程序中需要死锁

时间:2012-04-04 02:05:09

标签: servlets deadlock

由于某种原因,我想检查Web应用程序中的死锁是如何发生的,所以这就是我使用下面的代码的原因,但是当我部署Web应用程序并测试它时,我没有陷入僵局的境地!任何帮助

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletException;
import java.util.ArrayList;
import java.io.IOException;
import java.io.PrintWriter;

public class DeadLockServlet extends HttpServlet
{
public static ArrayList student = new ArrayList();
public static ArrayList employee = new ArrayList();
PrintWriter out;

@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
    String lsAction = request.getParameter("action");
    String lsValue = request.getParameter("data");

    out = response.getWriter();
    String msg = "";
    if (lsAction != null)
    {
        if (lsAction.equals("addStudent"))
        {
            addStudent(lsValue);
            msg = "Student added: "+lsValue;
        }
        else if (lsAction.equals("addEmployee"))
        {
            addEmployee(lsValue);
            msg = "Employee added: "+lsValue;
        }
    }
    else
    {
        msg = "Invalid Request";
    }

    request.setAttribute("msg", msg);
    request.setAttribute("student", student);
    request.setAttribute("employee", employee);
    request.getRequestDispatcher("index.jsp").forward(request, response);
}

public void addStudent(String lsValue)
{
    synchronized (employee)
    {
        synchronized (student)
        {
            if (lsValue != null && !lsValue.equals(""))
            {
                student.add(lsValue);
            }
        }
    }
}

public void addEmployee(String lsValue)
{

    synchronized (student)
    {
        synchronized (employee)
        {

            if (lsValue != null && !lsValue.equals(""))
            {
                employee.add(lsValue);
            }

        }
    }

}

}

1 个答案:

答案 0 :(得分:0)

虽然您的锁定顺序会导致死锁,但它需要准确的计时。如果不在调试器中运行该Web服务器并单步执行代码,我认为您不可能这样做。

如果您不想或不想这样做,请在addStudent和addEmployee中的两个synchronized块之间添加足够长的睡眠。说,每个1分钟。然后在大约同一时间从两个客户端点击servlet,一个执行addStudent,另一个执行addEmployee。

'student'请求处理线程将获得'employee'锁定,然后等待一下。 “员工”请求处理线程将获得“学生”锁定,然后等待。然后其中一个将唤醒,并尝试抓住另一个锁,另一个线程将执行相反的操作,并且presto:deadlock。

add ***方法应改为:

public void addStudent(String lsValue)
{
    synchronized (employee)
    {
        Thread.sleep(60 * 1000);
        synchronized (student)
        {
            if (lsValue != null && !lsValue.equals(""))
            {
                student.add(lsValue);
            }
        }
    }
}

public void addEmployee(String lsValue)
{

    synchronized (student)
    {
        Thread.sleep(60 * 1000);
        synchronized (employee)
        {

            if (lsValue != null && !lsValue.equals(""))
            {
                employee.add(lsValue);
            }
        }
    }
}

显然应该避免陷入僵局,但是,嘿,这是一个完整的问题!