Extra Thread decreases FPS in LibGDX Java - java

I am using a Thread to do some calculations related to the app that need to be done simultaneously but this Thread causes the FPS to drop (logically) and I wanted to know how to resolve the issue as the Thread is not doing any heavy calculations at all. Here is the code where I implement the Thread and the Thread itself.
incrementMass = new IncrementMass();
incrementMass.start();
// I added some extra functionality to the InputProcessor but I assume that is irrelevant
if(InputProcessor.isButtonUp() && InputProcessor.getButtonLetGo() == RIGHT && !isJustPressed) {
isJustPressed = true;
try {
incrementMass.join();
} catch(InterruptedException e) {
e.printStackTrace();
}
planets.add(new Planet(10, m, mouseOnWorld2.x, mouseOnWorld2.y));
} else if(Gdx.input.isButtonJustPressed(RIGHT)) {
isJustPressed = false;
incrementMass.restart();
}
The Thread:
/**
* Thread to increment the mass in a while loop.
*/
public class IncrementMass extends Thread {
/**
* Increments the mass when started.
*/
#Override
public void run() {
super.run();
while(Gdx.input.isButtonPressed(Input.Buttons.RIGHT)) {
MainScreen.m += 100;
System.out.println(MainScreen.m);
}
}
/**
* Resets the mass so the whole thing starts over (for the creation of a new planet)
*/
public void restart() {
MainScreen.m = 100000;
}
}
All this is called in the render() function of my Screen by the way.
I have one idea as to what is causing this: Every frame I create a new Thread which is not optimal but everything else I tried failed to actually perform my calculations correctly. It definitely solves the FPS problem to have the initiation of the Thread and the ´start()´ function in the constructor of my Screen but that for some reason messes with the incrementing of the mass and makes it a fixed value: the value I reset it to in ´restart()´
I've been trying to solve this but I'm baffled so here I am.

As said in the comment, there was no function for isButtonJustUp() which made it not be able to run sequentially. Therefore I made a Thread so that it was sequential which is not a good implementation of Threads. I've come up with a solution:
if(Gdx.input.isButtonPressed(RIGHT)) {
m += 100;
} else if(InputProcessor.isButtonJustUp() && InputProcessor.getButtonLetGo() == RIGHT) {
planets.add(new Planet(10, m, mouseOnWorld2.x, mouseOnWorld2.y));
m=0;
}
I haven't made isButtonJustUp() yet but it is the best way rather than implementing an unnecessary Thread.

Related

Why is the inventory updating?

I am using Bukkit API 1.8 with Java 7.
I have a repeating task that loops through all the players on the server and sets their armor randomly to either leather, chainmail, etc...
When I use the method setHelmet,setChestplate, etc... I update their inventory like usual, but since this task is running every 6 ticks, it runs fast. Therefore, when a player tries to fire a bow, the bow resets its power every time this task runs.
Since I knew it was a problem with updating the inventory, I tried removing the updateInventory method.
After doing this the armor still got put on and changed, but the bow was still being reset every time the task was ran.
How would I keep the bow from resetting while still keeping the task running?
My code:
#SuppressWarnings("deprecation")
public static void repeatEffect()
{
main.getServer().getScheduler().scheduleAsyncRepeatingTask(main, new Runnable()
{
#Override
public void run()
{
for(Player o : Bukkit.getOnlinePlayers())
{
Material M1 = Material.WOOL;
int num = rainbow.get(o.getName());
if(num==1)
{
M1 = Material.LEATHER_HELMET;
}
else if(num==2)
{
M1 = Material.CHAINMAIL_HELMET;
}
else if(num==3)
{
M1 = Material.GOLD_HELMET;
}
else if(num==4)
{
M1 = Material.IRON_HELMET;
}
else if(num==5)
{
M1 = Material.DIAMOND_HELMET;
}
rainbow.put(o.getName(), num+1);
if(rainbow.get(o.getName())>5)
{
rainbow.put(o.getName(), 1);
}
ItemStack rrhelm = createItemStack(M1, 1, "§a§lR§b§la§c§li§d§ln§e§lb§f§lo§a§lw §c§lH§d§le§e§ll§f§lm§a§le§b§lt", "§7Very special piece of armor");
o.getInventory().setHelmet(rrhelm);
}
}
}
, 6, 6);
}
If changing armour resets the players bow, you could work around it by only changing the armour of players who are joining, not wielding a bow or just after an EntityShootBowEvent.
To see if the player is wielding a bow, use:
org.bukkit.Bukkit.entity.Player player = ...;
boolean hasBowEquiped = player.getEquipment().getItemInHand().getData().getItemType().equals(Material.BOW);
After testing this some more, the only way I was able to reproduce the bow complication was by calling the deprecated updateInventory() method which you said you removed. I'm fairly certain that you still have this method somewhere in your code because I can't find anything else that would cause the bow to act this way (I was still able to fire the bow but the animation looks glitchy and the power of the arrow is sometimes incorrect).
The only difference between my code is that I used new ItemStack(M1) instead of your createItemStack() method to instantiate the helmet (also tried changing name, lore and amount). I was still able to shoot a bow just fine. Could the resetting of the bow/inventory have something to do with your createItemStack method?
There's no reason why you should be running this task asynchronously. You're accessing the Bukkit API from an asynchronous task or different thread which is a big no-no and can cause all kinds of tricky problems. Use the scheduleSyncRepeatingTask method to run the task in the same thread.
For simplicity's sake I randomly set a single armor slot (also tried all four) to either leather or iron every 6 ticks. Didn't seem to interfere with the bow. Could we see your code? Here is mine:
public void onEnable() {
this.getServer().getScheduler().scheduleSyncRepeatingTask(this, new Runnable() {
public void run() {
for (World world : Bukkit.getWorlds()) {
for (Player player : world.getPlayers()) {
if (Math.random() < 0.5) {
player.getInventory().setBoots(new ItemStack(Material.IRON_BOOTS));
} else {
player.getInventory().setBoots(new ItemStack(Material.LEATHER_BOOTS));
}
}
}
}
}, 0, 6);
}

How to force a while loop execute one runnable at a time.

I am trying to make a simple timer with uneven time intervals after each repetition.
I start as follows:
case R.id.start:
timerRuns = true;
startCycle();
break;
The cycle itself looks like this:
private void startCycle() {
pomodoroLeft = numPomodoro;
while(pomodoroLeft > 0) {
pomodoroLeft--;
actualSeconds = pomodoroLength * ONE_MINUTE;
setTimeAndRun(actualSeconds);
actualSeconds = shortLength * ONE_MINUTE;
setTimeAndRun(actualSeconds);
}
}
Method call:
private void setTimeAndRun(long timePeriod) {
runTime = timePeriod;
runnable.run();
}
And finally runnable itself:
private Runnable runnable = new Runnable()
{
public void run() {
if (timerRuns) {
runTime -= ONE_SECOND;
String str = String.format("%1$02d : %2$02d",
TimeUnit.MILLISECONDS.toMinutes(runTime),
TimeUnit.MILLISECONDS.toSeconds(runTime) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(runTime))
);
timeShown.setText(str);
mHandler.postDelayed(this, 1000);
if(timeShown.getText().toString().contentEquals("00 : 00")) {
stopClock();
//here goes the alarm.
}
}
}
};
My problem is that when I start the timer while loop seems to execute everything despite
incompliete run() of the previous method call. As a consequence timeShown TextView displays this actualSeconds = shortLength * ONE_MINUTE right away and skips 1 second each second because 2 runnables are running at the same time.
I want to achieve sequential execution here. What would be the best way to do so? Maybe implementing non-anonymous subclass and instantiate it every time would help?
Also, if you have any other suggestions that would improve my code I would greatly appreciate.
You should take a look at queues.
Here is a link to a similar question:
How to implement a queue of runnables
You should use the Executors.newSingleThreadExecutor()
http://developer.android.com/reference/java/util/concurrent/Executors.html#newSingleThreadExecutor%28java.util.concurrent.ThreadFactory
And here is a tutorial about the Executor:
http://tutorials.jenkov.com/java-util-concurrent/executorservice.html
here is also something that may help you understanding better multithreading in java:
Understanding multi-threading
hope this helps somehow.

How do I make concurrently running threads?

I want to have two separate threads running two different instances of different classes and I want them to execute the run command at the same time.
I've made a practice class to demonstrate the problem I'm having.
One racer counts forwards, the other counts backwards.
public class testCount {
public static void main(String args[]) {
testCount countCompetition = new testCount();
countCompetition.run();
}
public void run() {
(new Thread(new racer1())).start();
(new Thread(new racer2())).start();
}
public class racer1 implements Runnable {
public void run() {
for(int x = 0; x < 100; x++) {
System.out.println(x);
}
}
}
public class racer2 implements Runnable {
public void run() {
for(int y = 100; y > 0; y--) {
System.out.println(y);
}
}
}
}
My results
1
2
... All the way to 100
100
100
99
... All the way back down
1
What I want
1
100
2
99
3
98
They don't need to be taking turns like that, but they do need to be working at the same time, instead of one after the other.
Any hints, advice or code snippets would be greatly appreciated.
I think all the answers so far are missing the point.
Your existing logic does enable your two threads to both execute concurrently, but this is not evident because your numbers only go up to 100, and the execution will usually stay with a specific thread for more than 1 instruction at a time, otherwise there would be a large amount of overhead in switching between the currently executing thread all the time. In your case, the JVM is deciding to execute your first thread long enough for it to print out 100 numbers before "context switching" to the 2nd thread. The JVM might choose to execute the threads differently, so the result you are seeing is not guaranteed to be the same every time.
If you increase your numbers even to 1000 you will (probably) see the two threads interleaving somewhat. You will still have large runs where one thread prints out a lot of numbers in a row because it is more efficient for the JVM to execute one thread for a while before switching, instead of context switching between every instruction.
Adding Thread.sleep(1) is not a good solution as you are adding an unneccessary delay. Sure, for 100 numbers this might not be noticable but for 10000 numbers you would have a delay of 10 seconds.
Is there any reason that you would require them to interleave to a higher degree than they already do? If there is then your simple model of running two threads concurrently is not sufficient. If not then just let the JVM decide the best order to run your threads in (which in the simple example you have given, means they probably won't interleave most of the time).
Just add Thread.sleep(1); in each racer class after System.out.println().
i.e. it will look like this:
public class racer1 implements Runnable {
public void run() {
for(int x = 0; x < 100; x++) {
System.out.println(x);
try {
Thread.sleep(1);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
}
You need to write a basic wait and notify system. One task needs to notify the other that he has fished the work. Basic idea can be derived from below code. create 2 tasks, one to count forward and one to count backward
Runnable task = new Runnable() {
public void run() {
System.out.println("woohooTwo");
synchronized (t) {
while (true) {
System.out.println("---" + Thread.currentThread().getName() + "--" + t.i.getAndIncrement());
t.notifyAll();
try {
Thread.sleep(1000);
t.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
};

Execute method from a different thread than the one it's called from

I am working on a game using the thread-per-client model. The game operates so that every half a second all of the players need to be updated. The updates all have to happen within the half a second interval, so they need to all be executed at the same time. My idea is to have a class that keeps track of when the "global update" needs to happen and then when the time comes, go through all of the players and tell it to update:
for(Player p : currentPlayers) {
p.update();
}
The problem is that since every player has their own thread, I want the player to take advantage of that fact since it is already there. If I go through the updates from a different class, then there is one thread executing what a couple hundred threads could be doing individually. How can I design it so that if a thread calls method 'update()' in class Player, a different thread than the one that called it executes it, or perhaps a different approach that can achieve the same goal?
If you need any clarification, please ask! Thanks a lot!
UPDATE: What do you guys think of this (I can't figure out how to format long amounts of code in posts!):
UPDATE 2: Just realized I would need to know when all of the players finish updating to reset the last time...
public class PseudoExample implements Runnable
{
// Assume 'players' is full of active players.
private Player[] players = new Player[100];
private long lastUpdate = System.currentTimeMillis();
public void run()
{
while (true)
{
if (System.currentTimeMillis() - lastUpdate >= 500)
{
for (Player p : players)
{
p.update = true;
}
}
try
{
Thread.sleep(10);
} catch (InterruptedException e)
{
}
}
}
private class Player implements Runnable
{
private boolean update = false;
public void run()
{
while (true)
{
if (update)
{
// Do updating here ...
}
try
{
Thread.sleep(10);
} catch (InterruptedException e)
{
}
}
}
}
}
I think the best way to handle this would be instead of calling p.update(), you could send an asynchronous message to p. This would use the Handler functionality. This is probably the cleanest way, although I believe some (likely trivial) overhead will occur from the message passing.
So, in your ticking thread (i.e. the one that calls the global update), you would have a reference to a Handler object for each client thread. Then, you look would look like
for (Player p : currentPlayers) {
p.handler().sendMessage(); // this isn't exactly the syntax
}
and in your Player, you would have a PlayerHandler object that extends Handler and overrides handleMessage(Message).
EDIT: the comments on the question are good ones - don't use more threads than you need to. They might seem to be the "right" abstraction, but they introduce a ton of potentially tricky issues. If all of your computation needs to be done in between ticks, it might not matter whether it's done sequentially or not.

Correct use of wait()/notify() for a Tetris game

I’m writing a Tetris-like game for Android and I’m trying to implement the “real-time part”. I have something which seems to work, but I want to be sure that my implementation is correct.
What I want is:
The shapes are going down at a fixed rate (say that I want to wait n milliseconds each time the y of the shape is decremented)
The player can drop the shape at any time and the timer waiting for the n milliseconds must then be immediately interrupted and start again only for the next shape
When the shape is droped or when the shape cannot go down anymore, the game waits m milliseconds before creating another shape
The system have to be able to stop the thread at any time
What I am doing is the following (the system can stop the thread with interrupt()):
class TetrisThread extends Thread {
private int n = 3000; // for testing purposes, in the real game n will be smaller ;)
private int m = 1000;
#Override
public void run() {
doDraw();
while(!interrupted())
{
try {
synchronized (this) {
wait(n);
}
doPhysics();
doDraw();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
// This method is the one which will drop the shape, it is called from another thread
synchronized public boolean onTouch([…]) {
[…]
// The shape has to be dropped
dropShape();
notify();
[…]
}
private void doPhysics() throws InterruptedException {
[…]
// The shape cannot go down or has been dropped
sleep(m);
createNewShape();
[…]
}
}
In particular, the part synchronized(this) { wait(n); } looks funny because if I understand correctly this will take a lock on this and release it immediately.
But wait() requires to be used in a synchronized(this) block (why?) and I cannot either synchronize the whole run() method, because then if I try to drop three times the shape during the sleep(m) call, then the three next shapes will be automatically dropped (which is not what I want).
Does this seem correct to you?
Do you have any correction, advice, or remark?
Thank you :-)
The wait() method is used to make the current running thread to wait the object invoking wait() invoke notify() (in this case this). The synchronized(this) part needed to make sure only one thread at that time accessing this.
You can't synchronize the whole run() method, because the run() is from the parent (Thread) class and the parent didn't use synchonized in the declaration.
I don't know how to solve your other problem because I don't get how your program works right now.

Categories