Jump to content

How to create a new thread?


Recommended Posts

Posted

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'"

Posted (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 by Malcolm
  • Like 3
Posted
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'.

Posted
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. :doge:

 

Turn shots variable into an AtomicInteger :doge: 

and make sure the shots += 1 is incremented atomically (incrementing an int = multiple instruction sets: iinc and store?)

Posted
6 hours ago, Czar said:

 

Turn shots variable into an AtomicInteger :doge: 

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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...