运行() 中的这个引用在实现Runnable 时可以引用Thread 对象吗?

Can this reference in run() refer to Thread object when implementing Runnable?

抱歉,如果问题不清楚

我正在制作一个简单的多线程程序,它有一个链表来存储除主线程之外创建的所有线程。然后我想发送一些信号来终止主线程,但只有当所有其他线程都关闭时,我打算这样做,当线程关闭时,它将自己从链表中删除,然后主线程将检查该列表是否size == 是否为 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();

        }
    }
}

当 Shutdown_Handler.shutdown==true 时,main 将检查 threadList 是否为 null。问题是我不知道如何让线程从列表中删除自己。正如我所搜索的,对于普通对象,我可以创建这样的方法

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

但是,在线程的情况下,Class 实现 Runnable 所以 this 引用是对象而不是存储在列表中的线程

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

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

您还应该将此地图创建为同步地图(使用 Collections.synchronizedMap(...)

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

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

假设ClientThread是一个Runnable,基本代码为:

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

但是这有几个问题:

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

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

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

  4. 如果线程数比较大,HashSet<Thread>效率会更高