0

我有 1 个线程,唯一的工作就是从套接字中抓取 DatagramPackets 并将它们粘贴在缓冲区中。另一个线程在该缓冲区外工作,处理 DatagramPackets。我希望有一个线程池在该缓冲区之外工作。

我曾想过使用固定的线程池来做到这一点。为此,我是否需要创建池,然后提交足够的可运行文件以供执行以填满它?我曾希望有一种方式说“这是我希望你执行的线程/可运行,这是我想要运行的数量,GO!”。有这样的方法吗?固定线程池以外的其他东西更适合吗?

4

2 回答 2

2

Executors.newFixedThreadPool创建的固定线程池可以正常工作。

实现的内部语义是线程池将优先创建一个新线程,直到它达到其首选大小(核心池大小),这似乎是您想要的。

于 2012-08-31T21:36:04.087 回答
1

当您使用 an 时,ExecutorService您将作业提交Runnable到线程池,该线程池由池中的线程依次运行。您可以执行以下操作之一:

  1. 让每个人都Runnable坐在一个循环中,从一个BlockingQueue循环中出列以处理每个数据包。这可能比所有这些都围绕您的缓冲区对象同步更容易。就像是:

    public void run() {
       while (!shutdown) {
          packet = packetQueue.take();
          processPacket(packet);
       }
    }
    
  2. 或者,您可以将每个数据包作为作业本身提交到线程池,尽管这可能会增加您的对象负载。您可以处理每个数据包,提取有效负载,并使用处理有效负载的方法在Runnable有效负载周围创建一个包装器。run()类的内容Runnable将类似于:

    Payload payload;
    public void run() {
       // process packet here
       processPayload(payload);
    }
    

对于这两种机制,我会选择一个与您的处理器数量和处理任务的性质最匹配的固定线程数。下面的示例使用处理器的数量,但您可能希望为 GC 或其他任务减少一些。如果其他 IO 上的处理块,您可能需要更多。只有性能测试会告诉您最佳值是多少。

// start a pool that uses the number of threads that there are processors
ExecutorService threadPool = Executors.newFixedThreadPool(
    Runtime.getRuntime().availableProcessors());
于 2012-08-31T21:36:33.700 回答