0

My situation is as follows, I have a lot of objects and each of them needs to be associate with a separate thread. When the object is discarded, the corresponding thread needs to be terminated as well. Consider the situation like there are a lot of robots running independently in some maze, some of them may die after a while, their corresponding threads need to be removed.

so here is some sample code for creating the objects and threads(it could be done in a different way as the object wrapper described later),

List<MyObject> objects = new ArrayList();
List<Thread> threads = new ArrayList();
for(int i = 0; i < 10000/* could be arbitrary large number*/; i++){
    MyObject obj = new MyObject();
    threads.add(new Thread(){
        @Override
        public void run(){
            // do something with obj                    
        }
    });
}

Once the object is removed from the list, the thread should also be terminated, so here I have an intuitive idea that I create a map as the Thread Manager to manage this,

List<MyObject> objects = new ArrayList();
List<Thread> threads = new ArrayList();
Map<MyObject, Thread> threadManager = new HashMap();
for(int i = 0; i < 10000/* could be arbitrary large number*/; i++){
    MyObject obj = new MyObject();
    Thread thread = new Thread(){
        @Override
        public void run(){
            // do something with obj                    
        }
    };
    threads.add(thread);
    threadManager.put(obj, thread);
}

So now if the obj is removed from the list, I can find the entry in the map and stop the thread. Another idea would be create the object as a Runnable, so this object would be a wrapper for the thread.

public class MyObject implements Runnable {
    private volatile flag = true;
    public void run(){
        while(flag){//do somehting}
    }
    public void shutdown(){
        flag = false;
    }
}

So when the obj is removed from the list, just call shutdown for it.

So my question would be which one is better? Is there more elegant way to do this?

Simon
  • 629
  • 3
  • 8
  • One way would be to use an `AtomicBoolean` as a flag inside the object. In every iteration of the thread, check if the flag is false and if it is break out of any looping. – Chris Apr 27 '17 at 01:48
  • I would assume you are referring to the flag in the second way. If it is only used as a flag, volatile and AtomicXX should effectively be the same, since the AtomicXX trys to make the compare and swap atomic, the setting the flag is only the swap operation – Simon Apr 27 '17 at 02:09
  • My bad, you are correct. I didn't even see the second part of your question. I would probably go with your second approach. I believe best practice is to let threads terminate themselves internally (hence deprication of `.stop()`) – Chris Apr 27 '17 at 02:12
  • a thread already has a flag, that is the interruption flag. You can call `interrupt()` on the thread object and you can check if a running thread was interrupted using the `Thread.interrupted()` call. Refer to this answer http://stackoverflow.com/a/2127397/2657100 – nandsito Apr 27 '17 at 03:32
  • i don't know how `MyObject` is used and what those threads do, but depending on your architecture, it may be reasonable to create the my-objects inside the threads for better encapsulation, in case it makes sense – nandsito Apr 27 '17 at 03:35
  • @nandsito I think you are talking about the Thread not the Runnable, right? For the thread, I think you are right. MyObject is just a couple of instances, like the robots in my example, the threads are the controller of them, so they can all run around without a centralized manager. – Simon Apr 27 '17 at 05:58

0 Answers0