Java 在实现Runnable时,run()中的此引用能否引用线程对象?

Java 在实现Runnable时,run()中的此引用能否引用线程对象?,java,multithreading,linked-list,self-destruction,Java,Multithreading,Linked List,Self Destruction,对不起,问题不清楚 我正在制作一个简单的多线程程序,它有一个链表来存储除主线程外创建的所有线程。然后我想发送一些信号来终止主线程,但只有当所有其他线程都已关闭时,我才打算这样做,当线程关闭时,它将从链表中删除自己,然后主线程将检查列表大小==null或否 这是我的密码 public class MainProgram { //some global static variable static List<Thread> threadList = new LinkedL

对不起,问题不清楚

我正在制作一个简单的多线程程序,它有一个链表来存储除主线程外创建的所有线程。然后我想发送一些信号来终止主线程,但只有当所有其他线程都已关闭时,我才打算这样做,当线程关闭时,它将从链表中删除自己,然后主线程将检查列表大小==null或否

这是我的密码

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();

        }
    }
}

但是,对于线程,类implement
Runnable
因此
引用的是对象,而不是列表中存储的线程

我建议使用
HashMap
而不是
列表
。键可以是线程名称(例如
Thread.getName()
),值将是线程

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

现在,无论何时构造线程,都要将这个HashMap传递到它的构造函数中,线程可以保存对它的引用。因此,当线程即将终止时,它可以使用自己的线程名称作为要删除的键,将自己从
HashMap
中删除。

假设ClientThread是可运行的,基本代码是:

public class ClientThread implements Runnable {
    public void run() {
        // do stuff
        MainProgram.threadList.remove(Thread.currentThread());
    }
}
然而,这有两个问题:

  • 将有多个线程在没有正确同步的情况下对列表执行操作。这是不正确的,如果这样做,您很可能会出现间歇性故障

  • 除非
    run()
    finally
    块的列表中删除线程,否则异常终止的线程很可能不会被删除

  • 使用全局静态是一种糟糕的设计。更糟糕的设计是将其公开为裸(非私有)变量

  • 如果线程的数量可能很大,那么
    HashSet
    将更有效率


  • 如果我理解正确,那么您可以将ExecutorService与Java中可用的Futures一起使用。若要在多个线程中操作列表,应使用Collections.synchronizedList(..)或其他方法使其成为线程安全的。不能在静态方法中引用此方法。若要在Runnable类中获取当前线程,请使用thread.currentThread()。若要等待线程运行,只需在要暂停其执行的线程中执行t.join()。为什么?在所有非守护进程线程退出之前,程序不会退出。你不需要这些。
    Map<String, Thread> synchronizedMap = Collections.synchronizedMap(threadMap);
    
    public class ClientThread implements Runnable {
        public void run() {
            // do stuff
            MainProgram.threadList.remove(Thread.currentThread());
        }
    }