我有一个线程,唯一的工作是从套接字中获取DatagramPackets并将它们粘贴在缓冲区中 . 另一个线程在该缓冲区之外工作,处理DatagramPackets . 我想在缓冲区中运行一个线程池 .
我曾想过使用固定的线程池来做到这一点 . 为此,我是否需要创建池,然后提交足够的runnables来执行以填充它?我曾经希望有一种说法“这是我希望你执行的线程/ runnable,这就是我想要运行的多少,GO!” . 有没有这样做的方法?固定线程池以外的东西更适合吗?
当您使用 ExecutorService 时,您将 Runnable 作业提交给线程池,这些线程池依次由池中的线程运行 . 您可以执行以下操作之一:
ExecutorService
Runnable
BlockingQueue
public void run() { while (!shutdown) { packet = packetQueue.take(); processPacket(packet); } }
run()
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());
由Executors.newFixedThreadPool创建的固定线程池将正常工作 .
实现的内部语义是这样的,线程池将优先创建一个新线程,直到它达到其首选大小(核心池大小),这似乎是你想要的 .
2 回答
当您使用
ExecutorService
时,您将Runnable
作业提交给线程池,这些线程池依次由池中的线程运行 . 您可以执行以下操作之一:Runnable
坐在循环中,从循环中的BlockingQueue
出发来处理每个数据包 . 这可能比他们在缓冲区对象周围进行同步更容易 . 就像是:run()
方法在有效负载周围创建一个Runnable
包装器 .Runnable
类的内容类似于:使用这两种机制,我会选择一个最符合您的处理器数量和处理任务性质的固定线程数 . 下面的示例使用了处理器的数量,但您可能需要为GC或其他任务关闭一些 . 您可能希望在其他IO上的处理块上添加更多内容 . 只有性能测试才能告诉您最佳值 .
由Executors.newFixedThreadPool创建的固定线程池将正常工作 .
实现的内部语义是这样的,线程池将优先创建一个新线程,直到它达到其首选大小(核心池大小),这似乎是你想要的 .