2016-09-20 28 views
0

我有一个奇怪的问题,在这里我想使这是使用一个线程来实现蜱更新系统的程序,使用下面的代码:爪哇 - 线程停止没有任何迹象

@Override 
public void run(){ 
    long lastTime = System.nanoTime(); 
    long deltaTime; 
    float passedTime = 0; 
    long ticks = 0; 

    while(true){ 
     long currentTime = System.nanoTime(); 

     deltaTime = currentTime - lastTime; 
     lastTime = currentTime; 

     passedTime += deltaTime/tickTime; 

     if(passedTime * 20 > ticks){ 
      ticks++; 
      tick(); 

      System.out.println(ticks); 
     } 
    } 
} 

这工作正常,除了事实上,在161滴答完成后,它停止运行,它不会抛出任何东西,没有例外,没有错误,没有任何东西。 然而只要我做到以下几点:

@Override 
public void run(){ 
    long lastTime = System.nanoTime(); 
    long deltaTime; 
    float passedTime = 0; 
    long ticks = 0; 
    long useless = 0; 

    while(true){ 
     long currentTime = System.nanoTime(); 

     deltaTime = currentTime - lastTime; 
     lastTime = currentTime; 

     //Don't focus on this bit, I know it's a bit odd. 
     passedTime += deltaTime/tickTime; 

     if(passedTime * 20 > ticks){ 
      ticks++; 
      tick(); 

      System.out.println(ticks); 
     } 

     useless++; 
     System.out.print(useless); 
    } 
} 

,现在突然就没有问题运行?

有没有人有任何想法这可能是由于?提前致谢!

+0

你的方法'tick()'是什么? – SubOptimal

+1

在第一次迭代161次后,JVM已经优化了循环的执行,直到'deltaTime fabian

+0

@SubOptimal it调用该程序的所有更新方法,目前onlu调用一种方法来计算某些对象之间的引力吸引力。 – SchoolJava101

回答

2

添加print语句修复iussue的原因是因为您在旋转。

如果一个线程执行一个没有阻塞/ io /其他线程的紧密循环,它将只会旋转并占用cpu,导致所有其他线程获得更少的资源。

为了解决这个问题(作为临时措施),您可以添加一个Thread.sleep(0),这将释放其他线程的CPU以获取CPU时间。

一个更加持久的解决方案应该是组合一些机制来在您的流程之间进行通信(也许是BlockingQueue),以便您的线程可以花费大部分时间等待/阻止。

+0

如果这只用于程序中的定时,并且不需要进行线程间通信,那么BlockingQueue是否仍然是理想的?你能够推荐任何好的教程吗?再次感谢! – SchoolJava101

+0

@ SchoolJava101 - 如果只是您需要的时间,您可以考虑一个[TimerTask](https://docs.oracle.com/javase/7/docs/api/java/util/TimerTask.html)。 – OldCurmudgeon

+0

@ SchoolJava101 - 另外一个[ScheduledThreadPoolExecutor](https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledThreadPoolExecutor.html)可能是一个更灵活的选项。 – OldCurmudgeon