有没有办法确保将线程分配给指定的对象集?

Sam*_*erg 10 java multithreading threadpool

我们正在开发一个应用程序,通过接收来自3个不同来源的消息,可以影响一组对象.每条消息(来自任何来源)都有一个对象作为其目标.每个消息接收器将在其自己的线程上运行.

我们希望消息的处理(在接收之后)尽可能高速,因此针对目标对象的消息处理将使用来自线程池的另一个线程来完成.消息的处理将比从发送者读取/接收消息花费更长的时间.

我认为如果池中的每个线程仅专用于特定的一组对象,它会更快,例如:

Thread1 -> objects named A-L
Thread2 -> objects named M-Z
Run Code Online (Sandbox Code Playgroud)

每组对象(或线程)都有一个专用的消息队列待处理.

我的假设是,如果所需的唯一线程同步是在每个接收线程和一个处理线程之间,在需要将消息放入阻塞队列的持续时间内,它将比随机分配工作线程以处理更快消息(在这种情况下,可能有2个不同的线程与同一对象的消息).

我的问题实际上是两个部分:

  1. 人们是否同意将工作线程专用于特定对象集合是更好/更快的方法?

  2. 假设这是一种更好的方法,现有的Java ThreadPool类是否有办法支持这种方法?或者它是否要求我们编写自己的ThreadPool实现?

感谢您提供的任何建议.

Gra*_*ray 8

我假设总体目标是尝试最大化这些入站消息的并发处理.您有来自3个来源的接收器,需要将消息放入池中,以便进行最佳处理.因为来自3个源中的任何一个的消息可能处理无法同时处理的同一目标对象,所以您希望将消息分开,以便可以同时处理它们,但前提是它们保证不引用相同的目标对象.

我会hashCode()在你的目标对象上实现该方法(也许只是name.hashCode())然后使用该值将对象放入一个BlockingQueues 数组中,每个数组都有一个消耗它们的线程.使用数组Executors.newSingleThreadExecutor()就可以了.通过队列数修改哈希值模式并将其放入该队列中.您需要预先定义最大的处理器数量.取决于CPU处理的密集程度.

所以类似下面的代码应该工作:

 private static final int NUM_PROCESSING_QUEUES = 6;
 ...
 ExecutorService[] pools = new ExecutorService[NUM_PROCESSING_QUEUES];
 for (int i = 0; i < pools.length; i++) {
    pools[i] = Executors.newSingleThreadExecutor();
 }
 ...
 // receiver loop:
 while (true) {
    Message message = receiveMessage();
    int hash = Math.abs(message.hashCode());
    // put each message in the appropriate pool based on its hash
    // this assumes message is runnable
    pools[hash % pools.length].submit(message);
 }
Run Code Online (Sandbox Code Playgroud)

此机制的一个好处是您可以限制目标对象的同步.您知道同一目标对象只能由单个线程更新.

人们是否同意将工作线程专用于特定对象集合是更好/更快的方法?

是.这似乎是获得最佳并发性的正确方法.

假设这是一种更好的方法,现有的Java ThreadPool类是否有办法支持这种方法?或者它是否要求我们编写自己的ThreadPool实现?

我不知道任何完成此任务的线程池.但是,我不会编写您自己的实现.只需像上面的代码大纲一样使用它们.

  • 谢谢你的回答。请记住,`.hashCode()` 可能会返回一个负整数。为了安全使用:`Math.abs(hash)`。 (2认同)