2015-12-04 3 views
1

Я очень новичок в потоках, и я хочу, чтобы мой pathfinder запускал на нем отдельную тему.Запуск моих вычислений по поиску в отдельной теме

Для небольшого количества единиц (которые запрашивают путь при открытии игры) это работает некоторое время, но затем я получаю NullPointerException и IllegalThreadStateException.

... 
GoTo: New path for nr: 10. [9ms] 
Item: item picked up by: nr: 2 
Item: item picked up by: nr: 0 
GoTo: New path for nr: 1. [10ms] 
GoTo: New path for nr: 2. [2ms] 
GoTo: New path for nr: 0. [3ms] 
Item: item dropped by: nr: 11 
Item: item dropped by: nr: 2 
Item: item dropped by: nr: 12 
Item: item dropped by: nr: 20 
Item: item dropped by: nr: 0 
Exception in thread "Thread-38" java.lang.NullPointerException 
    at com.badlogic.gdx.utils.BinaryHeap.down(BinaryHeap.java:124) 
    at com.badlogic.gdx.utils.BinaryHeap.remove(BinaryHeap.java:72) 
    at com.badlogic.gdx.utils.BinaryHeap.pop(BinaryHeap.java:60) 
    at com.badlogic.gdx.ai.pfa.indexed.IndexedAStarPathFinder.search(IndexedAStarPathFinder.java:113) 
    at com.badlogic.gdx.ai.pfa.indexed.IndexedAStarPathFinder.searchNodePath(IndexedAStarPathFinder.java:93) 
    at com.badlogic.gdx.ai.pfa.indexed.IndexedAStarPathFinder.searchNodePath(IndexedAStarPathFinder.java:50) 
    at com.buckriderstudio.buriedkingdoms.Creatures.Jobs.GoTo.getPath(GoTo.java:93) 
    at com.buckriderstudio.buriedkingdoms.Creatures.Jobs.GoTo.access$000(GoTo.java:18) 
    at com.buckriderstudio.buriedkingdoms.Creatures.Jobs.GoTo$1.run(GoTo.java:47) 
GoTo: New path for nr: 2. [27ms] 
Exception in thread "LWJGL Application" java.lang.IllegalThreadStateException 
    at java.lang.Thread.start(Thread.java:684) 
    at com.buckriderstudio.buriedkingdoms.Creatures.Jobs.GoTo.perform(GoTo.java:62) 
    at com.buckriderstudio.buriedkingdoms.Creatures.Jobs.Hauling.perform(Hauling.java:40) 
    at com.buckriderstudio.buriedkingdoms.Creatures.Creature.update(Creature.java:52) 
    at com.buckriderstudio.buriedkingdoms.Creatures.CreatureHandler.update(CreatureHandler.java:50) 
    at com.buckriderstudio.buriedkingdoms.World.TestMap.update(TestMap.java:114) 
    at com.buckriderstudio.buriedkingdoms.BuriedKingdoms.render(BuriedKingdoms.java:49) 
    at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:215) 
    at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:120) 
GoTo: New path for nr: 12. [1ms] 
GoTo: New path for nr: 20. [4ms] 
GoTo: New path for nr: 0. [27ms] 

Сначала я попытался начать нить в конструкторе, где мне нужен путь. Раньше я смотрел его там, прежде чем начал нарезать резьбу. Теперь я переместил его в метод, который вызывается в цикле обновления, но получаю те же результаты.

public GoTo(final Creature creature, final Coordinate coordinate) { 
     test = new Thread() 
     { 
      @Override 
      public void run() { 
       super.run(); 
       getPath(creature, coordinate); 
      } 
     }; 
     //getPath(creature, coordinate); //Old way without threads 
    } 

Вслед вызывается каждый кадр, но он не должен называть нить несколько раз, так как он проверяет, если он жив, и когда он закончил он должен иметь путь.

@Override 
public boolean perform(final Creature creature) { 
    if (path == null) 
    { 
     if (!test.isAlive()) 
      test.start(); 


     return false; 
    } 

Я начал с этого потока код в конструкторе:

new Thread(new Runnable() { 
     @Override 
     public void run() { 
      getPath(creature, coordinate); 
     } 
    }).start(); 

Если я ставлю 100 единиц в моей игре на 1000x1000 человека вещи начинают идти не так сразу.

"C:\Program ... 
Exception in thread "Thread-3" java.lang.NullPointerException 
    at com.badlogic.gdx.utils.BinaryHeap.down(BinaryHeap.java:115) 
    at com.badlogic.gdx.utils.BinaryHeap.remove(BinaryHeap.java:72) 
    at com.badlogic.gdx.utils.BinaryHeap.pop(BinaryHeap.java:60) 
    at com.badlogic.gdx.ai.pfa.indexed.IndexedAStarPathFinder.search(IndexedAStarPathFinder.java:113) 
    at com.badlogic.gdx.ai.pfa.indexed.IndexedAStarPathFinder.searchNodePath(IndexedAStarPathFinder.java:93) 
    at com.badlogic.gdx.ai.pfa.indexed.IndexedAStarPathFinder.searchNodePath(IndexedAStarPathFinder.java:50) 
    at com.buckriderstudio.buriedkingdoms.Creatures.Jobs.GoTo.getPath(GoTo.java:82) 
    at com.buckriderstudio.buriedkingdoms.Creatures.Jobs.GoTo.access$000(GoTo.java:18) 
    at com.buckriderstudio.buriedkingdoms.Creatures.Jobs.GoTo$1.run(GoTo.java:43) 
    at java.lang.Thread.run(Thread.java:724) 
Exception in thread "Thread-1" java.lang.NullPointerException 
    at com.badlogic.gdx.ai.pfa.indexed.IndexedAStarPathFinder.search(IndexedAStarPathFinder.java:114) 
    at com.badlogic.gdx.ai.pfa.indexed.IndexedAStarPathFinder.searchNodePath(IndexedAStarPathFinder.java:93) 
    at com.badlogic.gdx.ai.pfa.indexed.IndexedAStarPathFinder.searchNodePath(IndexedAStarPathFinder.java:50) 
    at com.buckriderstudio.buriedkingdoms.Creatures.Jobs.GoTo.getPath(GoTo.java:82) 
    at com.buckriderstudio.buriedkingdoms.Creatures.Jobs.GoTo.access$000(GoTo.java:18) 
    at com.buckriderstudio.buriedkingdoms.Creatures.Jobs.GoTo$1.run(GoTo.java:43) 
    at java.lang.Thread.run(Thread.java:724) 
GoTo: New path for nr: 2. [2ms] 
Exception in thread "Thread-5" java.lang.NullPointerException 
Exception in thread "Thread-6" java.lang.NullPointerException 
    at com.badlogic.gdx.utils.BinaryHeap.down(BinaryHeap.java:124) 
    at com.badlogic.gdx.utils.BinaryHeap.remove(BinaryHeap.java:72) 
    at com.badlogic.gdx.utils.BinaryHeap.pop(BinaryHeap.java:60) 
    at com.badlogic.gdx.ai.pfa.indexed.IndexedAStarPathFinder.search(IndexedAStarPathFinder.java:113) 
    at com.badlogic.gdx.ai.pfa.indexed.IndexedAStarPathFinder.searchNodePath(IndexedAStarPathFinder.java:93) 
    at com.badlogic.gdx.ai.pfa.indexed.IndexedAStarPathFinder.searchNodePath(IndexedAStarPathFinder.java:50) 
    at com.buckriderstudio.buriedkingdoms.Creatures.Jobs.GoTo.getPath(GoTo.java:82) 
    at com.buckriderstudio.buriedkingdoms.Creatures.Jobs.GoTo.access$000(GoTo.java:18) 
    at com.buckriderstudio.buriedkingdoms.Creatures.Jobs.GoTo$1.run(GoTo.java:43) 
    at java.lang.Thread.run(Thread.java:724) 
Exception in thread "Thread-8" Exception in thread "Thread-7" java.lang.NullPointerException 
    at com.badlogic.gdx.utils.BinaryHeap.down(BinaryHeap.java:134) 
    at com.badlogic.gdx.utils.BinaryHeap.remove(BinaryHeap.java:72) 
    at com.badlogic.gdx.utils.BinaryHeap.pop(BinaryHeap.java:60) 
    at com.badlogic.gdx.ai.pfa.indexed.IndexedAStarPathFinder.search(IndexedAStarPathFinder.java:113) 
    at com.badlogic.gdx.ai.pfa.indexed.IndexedAStarPathFinder.searchNodePath(IndexedAStarPathFinder.java:93) 
    at com.badlogic.gdx.ai.pfa.indexed.IndexedAStarPathFinder.searchNodePath(IndexedAStarPathFinder.java:50) 
    at com.buckriderstudio.buriedkingdoms.Creatures.Jobs.GoTo.getPath(GoTo.java:82) 
    at com.buckriderstudio.buriedkingdoms.Creatures.Jobs.GoTo.access$000(GoTo.java:18) 
    at com.buckriderstudio.buriedkingdoms.Creatures.Jobs.GoTo$1.run(GoTo.java:43) 
    at java.lang.Thread.run(Thread.java:724) 
java.lang.NullPointerException 
    at com.badlogic.gdx.utils.BinaryHeap.down(BinaryHeap.java:134) 
    at com.badlogic.gdx.utils.BinaryHeap.remove(BinaryHeap.java:72) 
    at com.badlogic.gdx.utils.BinaryHeap.pop(BinaryHeap.java:60) 
    at com.badlogic.gdx.ai.pfa.indexed.IndexedAStarPathFinder.search(IndexedAStarPathFinder.java:113) 
    at com.badlogic.gdx.ai.pfa.indexed.IndexedAStarPathFinder.searchNodePath(IndexedAStarPathFinder.java:93) 
    at com.badlogic.gdx.ai.pfa.indexed.IndexedAStarPathFinder.searchNodePath(IndexedAStarPathFinder.java:50) 
    at com.buckriderstudio.buriedkingdoms.Creatures.Jobs.GoTo.getPath(GoTo.java:82) 
    at com.buckriderstudio.buriedkingdoms.Creatures.Jobs.GoTo.access$000(GoTo.java:18) 
    at com.buckriderstudio.buriedkingdoms.Creatures.Jobs.GoTo$1.run(GoTo.java:43) 
    at java.lang.Thread.run(Thread.java:724) 
GoTo: New path for nr: 7. [2ms] 
Exception in thread "Thread-10" java.lang.NullPointerException 
GoTo: New path for nr: 9. [0ms] 
Exception in thread "Thread-12" java.lang.NullPointerException 
Exception in thread "Thread-13" java.lang.NullPointerException 

Чтобы добавить к этому, я не волнует, если путь находкой занимает пару секунд, я просто не хочу, чтобы мой фреймрейт падать, потому что некоторые пути взять> 100мс на карте большего размера.

-Edit-

Я пытался с ним с будущей задачей:

общественного GoTo (окончательное Существо существо, конечная Coordinate координата) {

ExecutorService executor = Executors.newFixedThreadPool(2); 
    task = new FutureTask(new GetPath(creature.getLocation(), coordinate)); 
    executor.execute(task); 

      try { 
       path = (List<Coordinate>)task.get(); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } catch (ExecutionException e) { 
       e.printStackTrace(); 
      } 


    //getPath(creature, coordinate); 
} 

GetPath реализует Callable и, кажется, работает в приведенном выше примере. Но там он просто ждет завершения задачи/потока, поэтому я получаю те же результаты, что и без потоков, framedrop.

я ожидал бы, чтобы это работало в моем gameloop:

  if (task.isDone()) 
      { 
       try { 
        path = (List<Coordinate>)task.get(); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } catch (ExecutionException e) { 
        e.printStackTrace(); 
       } 
      } 
      else return false; 

Но она дает NullPointerExceptions.

java.util.concurrent.ExecutionException: java.lang.NullPointerException 
    at java.util.concurrent.FutureTask.report(FutureTask.java:122) 
    at java.util.concurrent.FutureTask.get(FutureTask.java:188) 
    at com.buckriderstudio.buriedkingdoms.Creatures.Jobs.GoTo.perform(GoTo.java:56) 
    at com.buckriderstudio.buriedkingdoms.Creatures.Jobs.Hauling.perform(Hauling.java:40) 
//.... 
+0

Зачем ты удалил свой ответ? Я хотел опубликовать комментарий, но так как вы его удалили, это было невозможно. – Madmenyo

ответ

0

Если вы просто хотите использовать нить, чтобы вычислить некоторый результат и не хотите, чтобы управлять жизненным циклом, попробуйте с помощью FutureTask и ExecutorService в пакете параллелизма.

Я нашел образец here.

И я настоятельно рекомендую вам прочитать «Java Concurrency in Practice», если вы действительно хотите понять эти проблемы.

+0

Образец хорош, но функциональность точно такая же, как без Threads. В цикле for он просто ждет завершения потоков, поэтому я получаю кадры. Как-то я не могу сделать 'if (task.isDone)' и поставить 'try/catch' там в моем gameloop, так как получаю другие' NullPointerExceptions'. – Madmenyo

Смежные вопросы