Я очень новичок в потоках, и я хочу, чтобы мой 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)
//....
Зачем ты удалил свой ответ? Я хотел опубликовать комментарий, но так как вы его удалили, это было невозможно. – Madmenyo