0

コンテナにスレッドを格納します。時間の経過とともに、これらのスレッドの一部は実行され、一部は停止します。私が達成したいのは、コンテナからデッド(停止)スレッドを自動的に(または定期的に)削除することです。これを行う最善の方法は何ですか?

編集:スレッドを単純なリンクリストに保存します:

LinkedList<ServerThread> threadPool = new LinkedList<ServerThread>();

時間の経過とともに、スレッドを追加 (および明らかに削除) する必要があるため、このコンテナーは動的でなければなりません。

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) {
            }
        }
4

2 に答える 2

5

特別な理由がない限り、独自のスレッドリストを維持しないでください。ExcecutorServiceJava5以降で利用できる優れたクラスを使用することをお勧めします。次のようなものです。

// 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
    }
}

スレッドプールは、プール内で実行中のスレッドを維持します。スレッドは次のジョブで再利用され、プールにジョブがなくなり、シャットダウンされたときにシャットダウンされます。デッドスレッドを自分で刈り取る必要はありません。


編集

投稿したコードに関しては、完成したスレッドをプールから削除するには、次のように実行する必要があります。

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

プールに新しいスレッドを追加するたびにこれを行います。また、メソッド呼び出し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);
于 2012-05-23T16:46:21.283 に答える
1

を使用しTimerて、定期的TimerTaskにリストを実行し、デッド スレッドを削除するスケジュールを設定できます。これはスケッチです:

static final List<Thread> threads = new LinkedList<Thread>();
static final Timer timer = new Timer(true);
public static void main(String[] args) {
  timer.scheduleAtFixedRate(new TimerTask() {public void run() {
    for (Iterator<Thread> it = threads.iterator(); it.hasNext();)
      if (!it.next().isAlive()) it.remove();
  }}, 0, 10000);
}
于 2012-05-23T16:42:45.270 に答える