Thread question
- gabrielvpy
- Posts: 69
- Joined: 23 Jul 2015, 20:18
Thread question
Hello, I have a question. I have the following structure to process when a player uses an ability in my game:
The client sends the request to execute to the server, the ability handler sends it to the world simulator, the world simulator sends it to a the character class and it responds with the damage to the world simulator which then uses the extension to send the clients the damage. Same thing happens to sync up the animation.
Now I'm implementing a new ability that keeps doing damage. I need to tell the clients it began with an initial damage but then I need my thread to continue running. My question is, how can I create a new thread that keeps running even if the one that handle the request is done? I don't have access to the world simulator from my character class and don't want to put it there just for this ability.
The client sends the request to execute to the server, the ability handler sends it to the world simulator, the world simulator sends it to a the character class and it responds with the damage to the world simulator which then uses the extension to send the clients the damage. Same thing happens to sync up the animation.
Now I'm implementing a new ability that keeps doing damage. I need to tell the clients it began with an initial damage but then I need my thread to continue running. My question is, how can I create a new thread that keeps running even if the one that handle the request is done? I don't have access to the world simulator from my character class and don't want to put it there just for this ability.
We made an awesome GPS - MOBA.
Try it out here: Get Fhacktions
Try it out here: Get Fhacktions
Re: Thread question
Hi,
you can use scheduled tasks. A task is not a thread and it is more efficient because it reuses threads from a thread pool.
See here:
http://docs2x.smartfoxserver.com/Gettin ... wtos#item7
The task will run every X seconds, milliseconds, or whatever you specify and it will keep generating damage on every cycle.
You can use the system's Scheduler or, if you are running hundreds of tasks, you could create your own Scheduler and keep it in the main Extension class.
Makes sense?
you can use scheduled tasks. A task is not a thread and it is more efficient because it reuses threads from a thread pool.
See here:
http://docs2x.smartfoxserver.com/Gettin ... wtos#item7
The task will run every X seconds, milliseconds, or whatever you specify and it will keep generating damage on every cycle.
You can use the system's Scheduler or, if you are running hundreds of tasks, you could create your own Scheduler and keep it in the main Extension class.
Makes sense?
- gabrielvpy
- Posts: 69
- Joined: 23 Jul 2015, 20:18
Re: Thread question
I'm familiar with the scheduler but I don't want to use it because I won't need i most of the time. I don't want to have a task asking every second if he need to do something if it will have work just 5% of the time at most. I mean, wouldn't that be a waste of resource? If I don't have another option I'll obviously just do that. But I want to know for certain that I don't have another way to do that.
We made an awesome GPS - MOBA.
Try it out here: Get Fhacktions
Try it out here: Get Fhacktions
Re: Thread question
It's not waste of resources, you can rest assured, but more importantly can't you set the frequency at which the task should run more precisely?
Why should it run every second if it's meant to be execute every once in a while? I am not sure I fully understand your use case.
In any case running tasks in a Scheduler is much, much better than manually creating and destroying your own threads.
cheers
p.s. = Sorry I didn't realize this was posted under SFS PRO, and not SFS2X. In any case the solution applies for both, even though my first answer was assuming you were using SFS2X.
If you're using the PRO I'd recommend using the ScheduledThreadPoolExecutor from the JDK:
https://docs.oracle.com/javase/7/docs/a ... cutor.html
In SFS2X we expose a TaskScheduler object which wraps the above and it's a bit more convenient to use, especially for beginners.
Why should it run every second if it's meant to be execute every once in a while? I am not sure I fully understand your use case.
In any case running tasks in a Scheduler is much, much better than manually creating and destroying your own threads.
cheers
p.s. = Sorry I didn't realize this was posted under SFS PRO, and not SFS2X. In any case the solution applies for both, even though my first answer was assuming you were using SFS2X.
If you're using the PRO I'd recommend using the ScheduledThreadPoolExecutor from the JDK:
https://docs.oracle.com/javase/7/docs/a ... cutor.html
In SFS2X we expose a TaskScheduler object which wraps the above and it's a bit more convenient to use, especially for beginners.
- gabrielvpy
- Posts: 69
- Joined: 23 Jul 2015, 20:18
Re: Thread question
Oh, I'm sorry. I meant to post it SFS2X. Can you move it please?
I guess I didn't explain myself very well. I have an ability that has to respond the client informing the inicial amount of damage done but also needs to keep taking life from the character that took the punch. I wanna do that by having my extension working as a usual thread that creates another thread that keeps doing the damage. This ability won't be used that often so I don't want a Task scheduled just for this ability.
I guess I didn't explain myself very well. I have an ability that has to respond the client informing the inicial amount of damage done but also needs to keep taking life from the character that took the punch. I wanna do that by having my extension working as a usual thread that creates another thread that keeps doing the damage. This ability won't be used that often so I don't want a Task scheduled just for this ability.
We made an awesome GPS - MOBA.
Try it out here: Get Fhacktions
Try it out here: Get Fhacktions
Re: Thread question
I have moved the discussion, no problem.
Well then, if you don't want to use the Scheduler I think the problem is already solved
Well then, if you don't want to use the Scheduler I think the problem is already solved
- gabrielvpy
- Posts: 69
- Joined: 23 Jul 2015, 20:18
Re: Thread question
I'm gonna try to explain myself again. I need thread A to do something and create thread B that will do some other thing. When A is done it can die but B needs to keep running. How do I do that?
We made an awesome GPS - MOBA.
Try it out here: Get Fhacktions
Try it out here: Get Fhacktions
Re: Thread question
I think I've already replied to that, let me clarify in the light of your last request:
Thread A is the thread from the Extension Controller executing your custom action.
Thread B is the thread from the Scheduler executing the repetitive task (cause damage).
So Thread A does its job, creates the Task and returns. As you are asking.
The difference with creating a new Thread B is that:
1) you're using a thread pool, which is more efficient and doesn't require creating and managing threads manually
2) the task can run once, twice, 30 times, 100 times... for as long as you need it, it will only occupy one thread for the short time of executing your task (e.g. nanoseconds) and release it right after
The solution is more scalable and efficient than creating and managing threads manually. Given the advances that Java has done since version 5 in terms of Executors and thread pools I don't see the need for manually working with threads any longer.
cheers
Thread A is the thread from the Extension Controller executing your custom action.
Thread B is the thread from the Scheduler executing the repetitive task (cause damage).
So Thread A does its job, creates the Task and returns. As you are asking.
The difference with creating a new Thread B is that:
1) you're using a thread pool, which is more efficient and doesn't require creating and managing threads manually
2) the task can run once, twice, 30 times, 100 times... for as long as you need it, it will only occupy one thread for the short time of executing your task (e.g. nanoseconds) and release it right after
The solution is more scalable and efficient than creating and managing threads manually. Given the advances that Java has done since version 5 in terms of Executors and thread pools I don't see the need for manually working with threads any longer.
cheers
- gabrielvpy
- Posts: 69
- Joined: 23 Jul 2015, 20:18
Re: Thread question
Now I understand what you mean. But how do I call the schedule to just run once?
This is my current setup. My scheduler restores shields. Do I use a new scheduler?
This is my current setup. My scheduler restores shields. Do I use a new scheduler?
Code: Select all
private class TaskRunner implements Runnable
{
private World world;
TaskRunner(World world){
this.world = world;
}
public void run()
{
List<Avatar> players = this.world.getPlayers();
for (int i = 0; i < players.size(); i++) {
if(players.get(i).restaurarEscudo()) clientUpdateHealth(players.get(i));
}
}
}
// Keeps a reference to the task execution
private ScheduledFuture<?> taskHandle;
@Override
public void init()
{
trace("Batalla Extension -- started");
world = new World(this); // Creating the world model
addRequestHandler("sM", SpawnMeHandler.class);
....//other handlers
SmartFoxServer sfs = SmartFoxServer.getInstance();
taskHandle = sfs.getTaskScheduler().scheduleAtFixedRate(new TaskRunner(world), 0, 1, TimeUnit.SECONDS);
}
@Override
public void destroy()
{
super.destroy();
taskHandle.cancel(true);
trace("Batalla Extension -- stopped");
}
We made an awesome GPS - MOBA.
Try it out here: Get Fhacktions
Try it out here: Get Fhacktions
Re: Thread question
There are two main methods in the Scheduler :
.schedule(...)
.scheduleAtFixedRate(...)
The former is what you need, if you want to run the task once and be done with it.
Not necessarily. SmartFoxServer already runs a global scheduler and you can use it for your own tasks too.
If you plan to run hundreds and hundreds of tasks you can reconfigure the number of threads it uses from the AdminTool > Server Settings. Otherwise you're good to go.
.schedule(...)
.scheduleAtFixedRate(...)
The former is what you need, if you want to run the task once and be done with it.
Do I use a new scheduler?
Not necessarily. SmartFoxServer already runs a global scheduler and you can use it for your own tasks too.
Code: Select all
SmartFoxServer.getInstance().getTaskScheduler()
If you plan to run hundreds and hundreds of tasks you can reconfigure the number of threads it uses from the AdminTool > Server Settings. Otherwise you're good to go.
- gabrielvpy
- Posts: 69
- Joined: 23 Jul 2015, 20:18
Re: Thread question
I've been using the Task Scheduler in it works great. But now I have a problem. When I stop my room extension I use the taskHandleTorreta.cancel(true) to cancel the threads but keep running. Why is that happening?
We made an awesome GPS - MOBA.
Try it out here: Get Fhacktions
Try it out here: Get Fhacktions
Re: Thread question
Hi,
you need to cancel all tasks you have started. Other than that it should work. Do you keep a reference to every started task?
cheers.
you need to cancel all tasks you have started. Other than that it should work. Do you keep a reference to every started task?
cheers.
- gabrielvpy
- Posts: 69
- Joined: 23 Jul 2015, 20:18
Re: Thread question
Yes I do. And that's the weird part. This is my setting. I have a few turret in my world and each turret has a "private ScheduledFuture<?> taskHandleTorreta" that is in charge of controlling who's near to attack. so when someone destroys it I can just kill that task. Also when the game is over I cancel every turret's task. But it stays alive. I have them print every once in a while a message to know if they are still working. What could I be doing wrong?
We made an awesome GPS - MOBA.
Try it out here: Get Fhacktions
Try it out here: Get Fhacktions
Re: Thread question
I have no idea, I suspect you need to debug your code better.
Maybe you should store all those tasks in a List so that when the game is over you can cycle through the list and kill all of them.
cheers
Maybe you should store all those tasks in a List so that when the game is over you can cycle through the list and kill all of them.
cheers
- gabrielvpy
- Posts: 69
- Joined: 23 Jul 2015, 20:18
Re: Thread question
I just tried this. And it didn't work. I gotta be doing something wrong here. This is my code:
ThreadTester.java
World.java
in my extension I have this method:
Let me explain how I want to make it work.
When my world is initialized I create a task with the runnable ThreasTester class that is supposed to run endlessly. But when the user named "vicente" wants to spawn I cancel the task. But it keeps running. This is the output I get:
ThreadTester is still alive
ThreadTester is still alive
ThreadTester is still alive
ThreadTester is still alive
empiezo a inicializar el avatar de : vicente
now I'll kill my Threadtest
I was interrupted!!!!!!!!
Thread.currentThread().isInterrupted(): false
Thread.currentThread().isAlive(): true
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at com.fhacktions.batalla.runnable.ThreadTester.run(ThreadTester.java:15)
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
ThreadTester is still alive
ThreadTester is still alive
ThreadTester is still alive
What am I doing wrong?
ThreadTester.java
Code: Select all
public class ThreadTester implements Runnable{
public ThreadTester(){
System.out.println("ThreadTester beggins working");
}
public void run()
{
while (true) {
System.out.println("ThreadTester is still alive");
try {
Thread.sleep(250);
} catch (InterruptedException e) {
System.out.println("I was interrupted!!!!!!!!");
System.out.println("Thread.currentThread().isInterrupted(): "+ Thread.currentThread().isInterrupted());
System.out.println("Thread.currentThread().isAlive(): " + Thread.currentThread().isAlive());
e.printStackTrace();
}
}
}
}
World.java
Code: Select all
...
private ScheduledFuture<?> threadTestertask;
public World(BatallaExtension extension) {
this.extension = extension;
threadTestertask = getExtension().callHiloIndependiente(new ThreadTester());
...
}
...
public boolean addOrRespawnPlayer(User user) {
Avatar player = getPlayer(user);
if (player == null) {
System.out.println("empiezo a inicializar el avatar de : " + user.getName());
if(user.getName().equalsIgnoreCase("vicente")){
System.out.println("now I'll kill my Threadtest");
threadTestertask.cancel(true);
}
....
in my extension I have this method:
Code: Select all
public ScheduledFuture<?> callHiloIndependiente(Runnable task){
return SmartFoxServer.getInstance().getTaskScheduler().schedule(task, 0, TimeUnit.SECONDS);
}
Let me explain how I want to make it work.
When my world is initialized I create a task with the runnable ThreasTester class that is supposed to run endlessly. But when the user named "vicente" wants to spawn I cancel the task. But it keeps running. This is the output I get:
ThreadTester is still alive
ThreadTester is still alive
ThreadTester is still alive
ThreadTester is still alive
empiezo a inicializar el avatar de : vicente
now I'll kill my Threadtest
I was interrupted!!!!!!!!
Thread.currentThread().isInterrupted(): false
Thread.currentThread().isAlive(): true
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at com.fhacktions.batalla.runnable.ThreadTester.run(ThreadTester.java:15)
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
ThreadTester is still alive
ThreadTester is still alive
ThreadTester is still alive
What am I doing wrong?
We made an awesome GPS - MOBA.
Try it out here: Get Fhacktions
Try it out here: Get Fhacktions
Who is online
Users browsing this forum: No registered users and 79 guests