只有当线程的字段值与已在运行的线程不匹配时,才在队列中执行线程。

huangapple go评论56阅读模式
英文:

Execute a thread in a queue only if its field value doesn't match an already running thread

问题

我有大量事件要处理,并且必须按顺序运行具有特定匹配属性的事件。让我们将这个属性称为“颜色”。如果我收到3个绿色事件和2个黄色事件,那么我必须按接收顺序依次运行所有3个绿色事件,因此它们必须一个接一个地运行。黄色事件也是如此。如果在第一个黄色事件完成之前,所有3个绿色事件都已处理,那也没问题,因为在不同颜色之间,顺序无关紧要。

现在,我还有一个可以同时运行的线程总数限制,而且有几十种颜色。因此,如果我得到20个不同颜色的事件,我不能同时运行它们。它们必须在线程池限制下。理想情况下,执行程序应始终首先运行最旧的事件,只要没有其他具有相同颜色的事件正在运行。

因此,当ThreadPoolExecutor需要出队一个Runnable时,它需要检查是否有相同颜色的其他可运行任务。如果有,它将查看队列中的下一个可运行任务,直到找到一个没有匹配颜色的可运行任务为止。然后,它将从队列中删除该任务,而不会干扰队列中任何其他元素的顺序。

我应该如何实现这种出队线程的方式在ThreadPoolExecutor中?或者还有其他更好的方法吗?

英文:

I have a large number of events coming in, and I must run the ones sequentially that have certain matching properties. Let's call this property "color". If I get 3 green events, and 2 yellow events, then I must run all the 3 green events in the order received, so they must be run one at a time. Same goes for the yellow events. If all 3 green events are processed before the first yellow event completes, that's fine, because across colors the order doesn't matter.

Now, I also have a limit to the total number of threads that can be run at once, and there's dozens of colors. So if I get 20 events of 20 different colors, I can't run them all at once. They must be under the thread pool limit. Ideally, the executor always be running the oldest event first, so long as there is no other event with the same color currently running.

So, what needs to happen is when it comes time for the ThreadPoolExecutor to dequeue a Runnable, it needs to check to see if there are any other Runnables of the same color. If so, look to the next Runnable in the Queue, until it finally finds one that doesn't have a matching color currently running. Then it will remove that from the Queue, without disturbing the order of any of the other elements in the Queue.

How would I go about implementing this way to dequeue threads in the ThreadPoolExecutor? Or is there another, better, way to do this?

答案1

得分: 3

不同颜色可以并行处理,但相同颜色必须串行处理。

所以,与其让所有线程相互通信它们正在处理的颜色,我们可以为每种颜色创建一个专用队列,并由一个线程处理该队列。

因此,一个分发线程读取事件队列,并根据事件的颜色将其发布到相应的队列上。

现在,您指出不能有与颜色数量相同的线程,但颜色可以共享一个队列。这仍然保证了每种颜色的串行处理。

英文:

Different colors can be processed concurrently, but same colors must be processed serially.

So rather than trying to make all your threads communicate to one another what color they are doing let's just make a dedicated queue for each color, and one thread handling that queue.

So one distributor thread reads the event queue and based on the color of the event posts it on the appropriate queue.

Now you indicate that you can't have as many threads as there are colors, but colors can share a queue. That still guarantees the serial processing of each color.

答案2

得分: 1

以下是翻译好的部分:

答案由 bowmore 提供是正确的。以下是一些代码。

将各种颜色任务定义为实现接口 hasColorRunnableCallable,该接口要求实现方法 getColor。为所有可能的颜色定义一个枚举 TaskColor

假设我们有四种颜色但只能使用两个线程。定义两个执行器服务对象,分别处理我们四种颜色的一对。将它们设置为单线程以逐个运行任务。

ExecutorService esGreenYellow = Executors.newSingleThreadExecutor();
ExecutorService esBlueRed = Executors.newSingleThreadExecutor();

编写一个接收所有类型为 hasColor 的任务的方法。该方法将绿色或黄色的任务推送到这两个执行器服务中的第一个,将另外两种颜色的任务推送到第二个执行器服务中。

英文:

The Answer by bowmore is correct. Here’s some code.

Define your various color tasks as a Runnable or Callable that implements an interface hasColor requiring a method getColor. Define an enum TaskColor for all possible colors.

Say we have four colors but a limit of two threads. Define two executor service objects, each to handle a pair of our four colors. Make them single-threaded to run tasks one on a time.

ExecutorService esGreenYellow = Executors.newSingleThreadExecutor() ;
ExecutorService esBlueRed = Executors.newSingleThreadExecutor() ;

Write a method that receives all tasks of type hasColor. That method shunts tasks of green or yellow into the first of those two executor services, and tasks of the other two colors into the second executor service.

huangapple
  • 本文由 发表于 2023年6月1日 06:57:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/76377753.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定