如何从容器中删除死线程

Won*_*abo 0 java multithreading

我将线程存储在容器中.随着时间的推移,其中一些线程将会运行,其中一些将会死亡.我想要实现的是:自动(或定期)从容器中删除死(停止)线程.做这个的最好方式是什么?

编辑:我将我的线程存储在一个简单的链表中:

LinkedList<ServerThread> threadPool = new LinkedList<ServerThread>();
Run Code Online (Sandbox Code Playgroud)

这个容器必须是动态的,因为随着时间的推移,我必须添加(并明显删除)线程.

EDIT2:这就是我目前管理线程的方式.正如你所看到的,我等待传入的连接,我不知道什么时候会到达,但是当它发生时,我必须在一个新线程中处理它.

while (!interrupted()) {
            try {
                Socket clientSocket = serverSocket.accept();
                if (portNumber == Server.SMTP_PORT_NUMBER) {
                    threadPool.add(new SMTPThread(clientSocket, db));
                    threadPool.getLast().setName("SMTP Thread " + ++threadCounter);
                } else {
                    threadPool.add(new POP3Thread(clientSocket, db));
                    threadPool.getLast().setName("POP3 Thread " + ++threadCounter);
                }

                threadPool.get(threadPool.size() - 1).start();

            } catch (SocketTimeoutException e) {
            } catch (IOException ioe) {
            }
        }
Run Code Online (Sandbox Code Playgroud)

Gra*_*ray 5

除非有特定原因,否则不应维护自己的线程列表.我建议使用ExcecutorService自Java 5以来可用的优秀类.如下所示:

// create a thread pool with 10 workers
ExecutorService threadPool = Executors.newFixedThreadPool(10);
// or you can create an open-ended thread pool
// ExecutorService threadPool = Executors.newCachedThreadPool();
for (Job job : jobsToDo) {
    threadPool.submit(new MyJobProcessor(job));
}
// once we have submitted all jobs to the thread pool, it should be shutdown
threadPool.shutdown();
...
public class MyJobProcessor implements Runnable {
    private Job job;
    public MyJobProcessor(Job job) {
        this.job = job;
    }
    public void run() {
        // process the job
    }
}
Run Code Online (Sandbox Code Playgroud)

线程池将负责维护池中正在运行的线程.线程将在下一个作业中重复使用,并且当池中没有其他作业且已关闭时将关闭.你自己不需要收获任何死线程.


编辑:

就您发布的代码而言,要从池中删除已完成的线程,您应该运行它们,如:

 Iterator<ServerThread> iterator = threadPool.iterator();
 while (iterator.hasNext()) {
     ServerThread thread = iterator.next();
     if (!thread.isAlive()) {
        // remove it from the linked list
        iterator.remove();
     }
 }
Run Code Online (Sandbox Code Playgroud)

每次向池中添加新线程后,我都会这样做.另外,请记住,LinkedList进行get(#)方法调用效率不高.我建议你调整你的代码:

            Socket clientSocket = serverSocket.accept();
            ServerThread serverThread;
            if (portNumber == Server.SMTP_PORT_NUMBER) {
                serverThread = new SMTPThread(clientSocket, db);
                serverThread.setName("SMTP Thread " + ++threadCounter);
            } else {
                serverThread = new POP3Thread(clientSocket, db);
                serverThread.setName("POP3 Thread " + ++threadCounter);
            }
            serverThread.start();
            threadPool.put(serverThread);
Run Code Online (Sandbox Code Playgroud)

  • 请注意,OP已经两次使用`list.getLast()`(高效),然后在第三种情况下突然"忘记"它.他可以第三次使用同一个电话.另外,如果他已经有自定义Thread子类,他应该已经在那些类中实现了线程名称INSIDE,构造函数只接受`threadCounter`. (2认同)