-1

Sorry if the question is unclear

I am making a simple multithread program that has a linked list to store all thread created except the main thread. Then I want to send some signal to terminate the main thread but only when all other threads have closed and I intend to do this by making that when the thread close, it will remove itself from linked list then the main thread will check if that list size == null or not

here is my code

public class MainProgram {
    //some global static variable
    static List<Thread> threadList = new LinkedList<Thread>();
    public void main() throws IOException {
        ServerSocket serverSocket;
        serverSocket = new ServerSocket(1234);
        while(true){
            if(Shutdown_Handler.shutdown==true){
                //wait for all other thread close/terminate
                return
            }
            Socket s = serverSocket.accept();
            ClientThread x = new ClientThread(s);
            Thread y = new Thread(x);
            threadList.add(y);
            y.start();

        }
    }
}

when Shutdown_Handler.shutdown==true the main will check the threadList if it is null. The problem is I don't know how to make the thread remove itself from the list. As what I have searched, for normal object, I can create method like this

public class someObject {
    public static void delete(){
        if(list.size = null) return;
        list.remove(this);
    }
}

However, in case of thread, the Class implement Runnable so this reference is to the object but not the thread stored in the list

aukxn
  • 231
  • 1
  • 4
  • 8
  • If I understood correctly then you can use ExecutorService with Futures which are available in Java. http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html – Moon Jun 02 '16 at 05:21
  • If you want to manipulate list in multiple threads, you should make it thread-safe, using Collections.synchronizedList(..) or something. – waltersu Jun 02 '16 at 05:23
  • You can't reference *this* in static method. If you want to get current thread in Runnable class, use Thread.currentThread(). – waltersu Jun 02 '16 at 05:25
  • If you want to wait till a thread is running, then you can simply do t.join() in thread whose execution you want to pause. [read it here](https://docs.oracle.com/javase/tutorial/essential/concurrency/join.html) – Varun Raval Jun 02 '16 at 05:31
  • Why? The program won't exit until all the non-daemon threads have exited. You don't need any of this. – user207421 Jun 02 '16 at 05:51

2 Answers2

2

I would recommend using a HashMap instead of a List. The keys can be the Thread Name (e.g. Thread.getName()) and the values will be the Threads.

Map<String, Thread> threadMap = new HashMap<String, Thread>();

You should also create this Map as a synchronizedMap (using Collections.synchronizedMap(...))

Map<String, Thread> synchronizedMap = Collections.synchronizedMap(threadMap);

Now, whenever you construct a Thread, you pass this HashMap into its constructor and the Thread can hold a reference to it. Therefore, when the Thread is about to terminate it can remove itself from the HashMap by using its own Thread name as the key to remove.

Michael Markidis
  • 4,163
  • 1
  • 14
  • 21
1

Assuming that ClientThread is a Runnable, the basic code is:

public class ClientThread implements Runnable {
    public void run() {
        // do stuff
        MainProgram.threadList.remove(Thread.currentThread());
    }
}

However this has a couple of problems:

  1. There are going to be multiple threads performing operations on a list without proper synchronization. That is incorrect, and you are liable to get intermittent failures if you do this.

  2. Unless run() removes the thread from the list in a finally block, a thread that terminates abnormally is liable to not get removed.

  3. It is bad design to use a global static. And worse design to expose it as a bare (non-private) variable.

  4. A HashSet<Thread> would be more efficient if the number of threads is liable to be large.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216