Sneh
Sneh

Reputation: 3737

How to change my Thread implementation to use ExecutorService

I had been making a game, and was using Threads in my program to carry out tasks. So let me explain the scenario a bit. I have a BattleManager class which implements Runnable and keep looping in the battle queue for battles, if there are any.

@Override
    public void run() {
        while(serverRunning){
            synchronized (battleQueue) {
                for(Battle battle : battleQueue){
                    if(battle != null){
                        if (battle instanceof WildBattle) {
                            if(!((WildBattle) battle).isBattleOver()){
                                ((WildBattle) battle).tryExecuteBattleTurn();
                            }else{
                                battleQueue.remove(battle);
                                battle = null;
                            }
                        }
                    }
                }
            }
            try {
                Thread.sleep(3);
            } catch (InterruptedException e)
                e.printStackTrace();
            }
        }
        currentThread = null;
    }

Then I check if battle is not over, and if not I try to execute the battle turn. Since there can be more than 100 battles running at the same time and there are complex calculations inside every battle, I inside WildBattle class spawn a child thread to execute the task, so that the battles run in parallel.

Here is the method which is invoked inside wild battle class, which spawns a new thread.

 public void tryExecuteBattleTurn() {
        if (!isBattleTurnRunning && battleThread == null) {

            battleThread = new Thread(new Runnable() {
                @Override
                public void run() {
                    //long startTime = System.currentTimeMillis();
                    executeBattle();
                    battleLog.setBattleLog("");
                    battleThread = null;
                    //System.err.println("Total execution time : " +(System.currentTimeMillis() - startTime));
                }
            }, "Battle thread");

            battleThread.start();
        }
    }  

Now the main question is, I want to learn about executor service and I read at few places that it is always better to use executor service rather than spawning new child threads. How can I change this to use executor service. I am not sure though. I am not a java expert and still learning the language so spare me if you see something is wrong, and please let me know if I can change anything to make it more efficient. Let me know if you are not clear about anything.

Upvotes: 3

Views: 942

Answers (1)

AdamSkywalker
AdamSkywalker

Reputation: 11609

I'll show you a basic example and you'll manage how to integrate it with your code

First you create ExecutorService somewhere in your application.

ExecutorService executorService = Executors.newFixedThreadPool(NUMBER_OF_THREADS);

You should choose NUMBER_OF_THREADS based on your application needs. Threads are not created immediately - only when you submit a task to service and there are no available threads for it. If all NUMBER_OF_THREADS are busy, task will wait in queue until one of the threads will be able to handle it. ExecutorService will reuse threads, this will save time on thread instantiation and is a generally good concept to work with threads.

Then you manage how to access executor service from your battles. Then, when you need to perform an asynchronous work you submit task to service:

executorService.submit(new Runnable() {
    @Override public void run() {
        // your code here
    }
}

If your application has a lifecycle and can be somehow shutdown, you'd like to shutdown ExecutorService as well. There are two options - shutdown() and shutdownNow(), first one waits for all current tasks to be executed, second one performs shutdown immediately and returns list of tasks that were not completed.

As was mentioned in comments, you should figure out how to preserve model state and organize thread synchronization based on your real situation.

Upvotes: 1

Related Questions