1

我想在我的 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");   
           }
    }
4

2 回答 2

6

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

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

至于为什么您的调用Thread.sleep()不起作用,那是因为您的 servlet 容器是多线程的。您的调用Thread.sleep()只是将处理当前 HTTP 请求的线程置于睡眠状态。但是容器仍然活着并且在踢。如果您发送另一个 HTTP 请求,它将抓取另一个与您进入睡眠状态的线程不同的线程来处理它。

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

我建议您花时间阅读 Oracle(前 Sun)提供的 Java 和 Java EE 教程。谷歌它,你会找到它。

== 编辑 ==

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

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

于 2013-07-08T12:39:38.330 回答
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具有自动刷新语义的 )。

于 2013-07-09T09:18:38.653 回答