需要有关 java 中 ExecutorService 的建议



嘿,所以我为ExecutorService的java文档选择了这个例子。我想确认这段代码的流程,Executors.newFixedThreadPool 将创建一个线程池(我猜(。因此,serversocket 将等待连接,一旦获得连接,它就会启动一个线程,所以现在 poolsize 减少了 1。线程完成执行后,poolsize 将再次增加 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
 }
}

线程完成执行后,poolsize 将再次增加 1,不是吗?

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

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

不是

立即,不是。 Handler run()方法完成后,Handler将超出范围。 但是,您必须等待垃圾回收器运行,然后才能释放Handler实例。 这将反过来释放Socket,然后成为垃圾回收本身的候选者。

如果您希望尽快发布Socket(我认为这是问题所在(,则应在run()方法结束时完成。 您可以在finally块中调用socket.close()(也可以将socket设置为null(。 建议使用类似以下内容的内容:

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();
       }
    }
}
线程

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

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

相关内容

  • 没有找到相关文章

最新更新