我想在我的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");
}
}
答案 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)
你当前的方法有很多问题,我会试着指出一些。
您的Player
显然已延伸Thread
。这是一个反模式;您应该只implements Runnable
并将课程实例传递给new Thread()
;
基于Servlet的Web应用程序的基本风格基于严格的请求 - 响应范例,其中尽快发生响应。您(可能)正在寻找的是“长响应”,异步风格。这可以通过Servlet 3.0中的新功能实现,但远远超出了这个答案的范围;
假设你只是想要去做一下,快速补丁就是追加
for (Player p : Player.e) p.join();
到您现有的doGet
方法。这将推迟doGet
的返回,直到你的所有子线程都死掉。您还需要定期flush
编写器强制立即将数据发送到客户端(或使用具有自动刷新语义的PrintWriter#println
。