睡在Java Web应用程序中

时间:2013-07-08 12:27:58

标签: java

我想在我的java应用程序中使用Thread.sleep()。但是不起作用。删除睡眠后程序有效。

在我的程序中,我正在运行多个线程,并希望每个线程以可变速度向前移动。有些人可能会被处理得更少一些。所以我使用随机数作为参数在每个中使用睡眠。 如果有另一种方法可以做到这一点。不用睡觉。

这是我使用睡眠功能的部分。

public void run()
    {
        Random r = new Random();
        int t;
        while(true)
        {
            if(total == 1)
            {
                // win();
                break;
            }
            if(doa == 1)
                break;
            // Player x = e[r.nextInt(20)%2];
            Player x = choose();
            x.attack(this, 10 + (power==1?5:0));
            if(r.nextInt(100)%(5 - (power==2?2:0)) == 0)
                System.out.println(" " + name + " used Potion effect (" + potionno++ + ") .. now " + name + "'s Health is " + (h+= 10 + r.nextInt(20))); 
            try
            {
                sleep(50 + r.nextInt(1000));
            }
            catch(InterruptedException c)
            {       ; }
        }
        if(doa == 1)) {
// and so on



   .

这是我用于启动的doGet函数

public void doGet(HttpServletRequest request, HttpServletResponse response)
           throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        String s;
        s = request.getParameter("name");           
        try{
           Player.out = out;
            Player.e[0] = new Player("Kartik",2);
            Player.e[1] = new Player(s,1);
            Player.e[2] = new Player("Anirudh",3);
            Player.e[3] = new Player("Vinita");
            Player.e[4] = new Player("Shivank");

            for(Player p: Player.   e)
                    p.start();

       }
           catch(Exception e)
           {
             out.print("WRONG");   
           }
    }

2 个答案:

答案 0 :(得分:6)

你不应该这样做,因为一般来说,Java EE / servlet容器假设它们的应用程序不会产生线程(或修改现有的线程的执行或配置,你正在使用Thread.sleep() )他们自己所有的威利威利。

这是可能的,但除非你知道自己在做什么,否则通常不赞成。看到这个简洁而又出色地解释原因的答案:https://stackoverflow.com/a/533847/201722

为什么你对Thread.sleep()的调用不起作用,这是因为你的servlet容器是多线程的。您对Thread.sleep()的调用只是将处理当前HTTP请求的线程置于休眠状态。但容器还活着并且在踢。如果您发送另一个HTTP请求,它将获取另一个与您暂停的不同的线程来处理它。

所以,从您的POV来看,它似乎无法正常工作。但它正在工作,你让可怜的线程进入休眠状态,容器 ok,这是另一个适合你的。碰巧你不知道到底发生了什么。

我建议您花时间浏览Oracle(前Sun.)Google提供的Java和Java EE教程,你会发现它。

==编辑==

我还建议OP阅读以下简明扼要的解释不分青红皂白地干预容器中的线程。

http://www.psionicwave.com/blog/2012/12/15/threading-in-web-containers/

答案 1 :(得分:2)

你当前的方法有很多问题,我会试着指出一些。

  1. 您的Player显然已延伸Thread。这是一个反模式;您应该只implements Runnable并将课程实例传递给new Thread();

  2. 基于Servlet的Web应用程序的基本风格基于严格的请求 - 响应范例,其中尽快发生响应。您(可能)正在寻找的是“长响应”,异步风格。这可以通过Servlet 3.0中的新功能实现,但远远超出了这个答案的范围;

  3. 假设你只是想要去做一下,快速补丁就是追加

    for (Player p : Player.e) p.join();
    

    到您现有的doGet方法。这将推迟doGet的返回,直到你的所有子线程都死掉。您还需要定期flush编写器强制立即将数据发送到客户端(或使用具有自动刷新语义的PrintWriter#println