Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Good practice for multi-threading

I have an app where when a "game" stats, it starts a couple different threads. I start the threads like so:

Thread thread = new Thread(new Runnable()
{
    public void run()
    {
        //...
    }
});

thread.setName("killMeAtEnd");
thread.start();

Later when the game ends i have a dispose() method inside of game which sorts through all of the running Threads and ends all of the Threads that have the name "killMeAtEnd". My question is, is this good practice? My intention is to keep my app running fast and clutter free, in my experience Threads that are left "hanging" tend to slow down the phone until the app is terminated. Is there a better way to do this? Is this even worth bothering about?

EDIT:

Here is my dispose() if anyone was interested. This code is within the class Game.

public void dispose()
{
    Thread threads[] = (Thread[])Thread.getAllStackTraces().keySet().toArray();
    for(int x=0;x<threads.length;x++)
    {
        Thread thread = threads[x];
        if(thread.getName().equalsIgnoreCase(KILL))
        {
            try
            {
                thread.interrupt();
            }catch(Exception e){Log.e(Viewer.GAME,Log.getStackTraceString(e));}
            thread = null;
        }
    }
}

public static final String KILL = "endOnDispose";
like image 566
John Avatar asked Mar 21 '12 01:03

John


2 Answers

You have the right idea, but there are some areas for improvement:

  1. Instead of querying the system for all running threads, just add your threads to a list whenever you create them. You can then terminate all the threads you created or wait for their completion (joining).
  2. Interrupt only interrupts a thread in a blocking state, so you need to have an additional flag that the thread checks periodically (i.e. after every "work cycle").
  3. Catch the interrupt exception inside your thread and handle it (i.e. exit gracefully).
like image 103
Kiril Avatar answered Sep 16 '22 19:09

Kiril


This isn't necessarily a bad solution, but there are a few issues:

  • If your threads are worker threads of the sort that handle one task to completion, there is likely a better design in which the thread ends itself. In other words, there is possibly a better flow of execution, that doesn't require being killed at the end.

  • When you say "sort through all the running Threads...", I imagine you're looking at ALL of the running threads in the JVM? as in something along the lines of this SO question? If that's the case, why aren't you just keeping a reference to all of the threads that your game owns instead, and then specifically killing them? As opposed to just looking for "killMeAtEnd"; I can't think of how your strategy could go wrong, but it seems a bit cleaner to keep track of your threads.

It definitely IS good practice to keep threads clean. If your threads are doing something less specific-task-oriented (e.g. waiting for network io, or something), then my first suggestion is somewhat irrelevant. I would just suggest being very careful about the design of how you keep your threads clean, because errors with threads can be a big pain.

like image 43
mfsiega Avatar answered Sep 17 '22 19:09

mfsiega