0

出于某种原因,我想检查 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);
            }

        }
    }

}

}

4

1 回答 1

0

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

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

'student' 请求处理线程将获得 'employee' 锁,然后坐下来稍等。'employee' 请求处理线程将获得 'student' 锁,然后坐下来等待。然后其中一个会醒来,并尝试抓住另一个锁,而另一个线程会做相反的事情,然后:死锁。

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);
            }
        }
    }
}

显然要避免死锁,但是,嘿,这完全是另一个问题!

于 2012-04-05T00:47:32.687 回答