Heiz Posted October 8, 2021 Share Posted October 8, 2021 I need to create a new thread to keep watching the player's hitpoints. I looked for some tutorials here on the forum, but none worked, could someone help me please?. I tried this: Event customEvent = new Event() { @Override public int execute() throws InterruptedException { return 0; } }; customEvent.setAsync(); execute(customEvent); But it returns a lot of errors: "Method does not override method from its superclass" "Cannot resolve method 'setAsync' in 'Event'" Quote Link to comment Share on other sites More sharing options...
Gunman Posted October 8, 2021 Share Posted October 8, 2021 @Heiz https://osbot.org/forum/topic/164541-how-do-you-handle-asyncthreads/ 1 Quote Link to comment Share on other sites More sharing options...
Malcolm Posted October 8, 2021 Share Posted October 8, 2021 (edited) I much prefer to create a class that implements the runnable interface. This way it makes it much cleaner (at least imo). Here is an example for my V2 slayer cannon shot listener. private Thread cannonThread; private CannonListener cannonListener; public void startCannonListener() { cannonListener = new CannonListener(this); cannonThread = new Thread(cannonListener); cannonThread.start(); } and the CannonListener class public class CannonListener implements Runnable { private final Main script; private int shots = 0; private final ArrayList<Integer> loopList = new ArrayList<Integer>(); public CannonListener(final Main script) { this.script = script; } @Override public void run() { script.log("Starting cannon listener..."); while (script.getBot().getScriptExecutor().isRunning() || script.getBot().getScriptExecutor().isPaused()) { if (script.getClassProvider().getFighting().getCombatMaintenance().hasPlacedCannon()) { final List<Projectile> list = script.getProjectiles().filter(f -> f.getId() == 53); for (Projectile proj : list) { if (!loopList.contains(proj.getLoopCycle())) { shots += 1; loopList.add(proj.getLoopCycle()); } } } Timing.waitCondition(() -> false, 100); } } public int getShots() { return shots; } public void resetShots() { this.shots = 0; } } Edited October 8, 2021 by Malcolm 3 Quote Link to comment Share on other sites More sharing options...
Heiz Posted October 8, 2021 Author Share Posted October 8, 2021 Thanks guys Quote Link to comment Share on other sites More sharing options...
dreameo Posted October 11, 2021 Share Posted October 11, 2021 On 10/7/2021 at 10:40 PM, Malcolm said: I much prefer to create a class that implements the runnable interface. This way it makes it much cleaner (at least imo). Here is an example for my V2 slayer cannon shot listener. private Thread cannonThread; private CannonListener cannonListener; public void startCannonListener() { cannonListener = new CannonListener(this); cannonThread = new Thread(cannonListener); cannonThread.start(); } and the CannonListener class public class CannonListener implements Runnable { private final Main script; private int shots = 0; private final ArrayList<Integer> loopList = new ArrayList<Integer>(); public CannonListener(final Main script) { this.script = script; } @Override public void run() { script.log("Starting cannon listener..."); while (script.getBot().getScriptExecutor().isRunning() || script.getBot().getScriptExecutor().isPaused()) { if (script.getClassProvider().getFighting().getCombatMaintenance().hasPlacedCannon()) { final List<Projectile> list = script.getProjectiles().filter(f -> f.getId() == 53); for (Projectile proj : list) { if (!loopList.contains(proj.getLoopCycle())) { shots += 1; loopList.add(proj.getLoopCycle()); } } } Timing.waitCondition(() -> false, 100); } } public int getShots() { return shots; } public void resetShots() { this.shots = 0; } } This is not thread safe. You need to guard access to 'shots'. Quote Link to comment Share on other sites More sharing options...
Czar Posted October 11, 2021 Share Posted October 11, 2021 56 minutes ago, dreameo said: This is not thread safe. You need to guard access to 'shots'. 48 minutes ago, Malcolm said: It's perfectly safe for my usage. Turn shots variable into an AtomicInteger and make sure the shots += 1 is incremented atomically (incrementing an int = multiple instruction sets: iinc and store?) Quote Link to comment Share on other sites More sharing options...
dreameo Posted October 11, 2021 Share Posted October 11, 2021 6 hours ago, Czar said: Turn shots variable into an AtomicInteger and make sure the shots += 1 is incremented atomically (incrementing an int = multiple instruction sets: iinc and store?) That would make it thread safe but programming logic would still be incorrect. You wouldn't want to reset the 'shots' counter while you're iterating over the 'projectiles list'. You would want to wait until that loop is finished and then allow the reset. Quote Link to comment Share on other sites More sharing options...
dreameo Posted October 11, 2021 Share Posted October 11, 2021 7 hours ago, Malcolm said: It's perfectly safe for my usage. Quote If multiple threads access the same mutable state variable without appropriate synchronization, your program is broken Quote Link to comment Share on other sites More sharing options...
Heiz Posted October 11, 2021 Author Share Posted October 11, 2021 11 minutes ago, dreameo said: How would you make that same cannon code then? Quote Link to comment Share on other sites More sharing options...