在java中需要有关ExecutorService的建议

时间:2012-08-29 18:38:34

标签: java concurrency executorservice

嘿所以我为ExecutorService的java文档选择了这个例子。我想确认这段代码的流程,Executors.newFixedThreadPool会创建一个线程池(我猜)。所以serversocket会等待一个连接,一旦它获得一个,它就会启动一个线程,所以现在poolize减少了1.一旦线程完成执行,poolize将再次递增1,不是吗?线程会放弃它使用的资源吗?

class NetworkService implements Runnable {
 private final ServerSocket serverSocket;
 private final ExecutorService pool;

 public NetworkService(int port, int poolSize)
   throws IOException {
 serverSocket = new ServerSocket(port);
 pool = Executors.newFixedThreadPool(poolSize);
}

 public void run() { // run the service
 try {
   for (;;) {
     pool.execute(new Handler(serverSocket.accept()));
   }
 } catch (IOException ex) {
   pool.shutdown();
  }
 }
}

class Handler implements Runnable {
 private final Socket socket;
 Handler(Socket socket) { this.socket = socket; }
 public void run() {
  // read and service request on socket
 }
}

3 个答案:

答案 0 :(得分:1)

  

一旦线程完成执行,poolize将再次递增1,不是吗?

是。线程将采取并运行下一个Handler

  

线程会放弃它使用的资源吗?

不是立即,不是。完成Handler run()方法后,Handler将超出范围。但是,您必须等待垃圾收集器在Handler实例发布之前运行。这将依次释放Socket,然后它就成为垃圾收集的候选者。

如果您希望尽快释放Socket(我认为这是问题),那么应该在run()方法结束时完成。您可以在socket.close()块中调用socket(并可能将null设置为finally)。建议使用以下内容:

class Handler implements Runnable {
    ...
    public void run() {
       try {
           // read and service request on socket
       } finally {
           // make sure we close the socket when the handler is finishing
           socket.close();
       }
    }
}

答案 1 :(得分:0)

所有线程都执行你的 Runnable 因此,如果您需要在完成任务之后进行任何清理应该从Runnable执行此操作。该池只是Producer - Consumer模式实现,负责管理线程的生命周期。
线程执行您在队列中传递的任务,因此在您的情况下,socket不会在线程之间重用。它的范围在Runnable

答案 2 :(得分:0)

由于它是fixedThreadPool,是的,每次将任务提交到池中时,池大小都会减少。一旦线程完成运行提交的runnable(或可调用),就会增加。 向固定线程池提交更多可运行数将被阻塞,直到池中的任何线程完成运行其先前提交的任务为止。