-
Notifications
You must be signed in to change notification settings - Fork 7.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
1.x: fix ExecutorScheduler and GenericScheduledExecutorService reorder bug #3760
Conversation
NONE = Executors.newScheduledThreadPool(0); | ||
NONE.shutdownNow(); | ||
SHUTDOWN = Executors.newScheduledThreadPool(0); | ||
SHUTDOWN.shutdown(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ew
I definitely don't like that library will create executor when this class will be loaded. Even without threads used it looks strange.
Maybe return new each time getInstance()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Executors don't start their thread until the first task is submitted.
I have trouble understanding how this solve the problem, could you please elaborate? |
Yes, ExecutorScheduler's worker needs a helper ScheduledExecutorService with a single thread only. But we don't want all ExecutorSchedulers to wait in a single thread for their time to run. This change, similar to how computation scheduler works, hands out single hreaded ScheduledExecutorServices on demand. |
Nice catch.
I vote for |
Agree with @zsxwing that correctness is more important than performance. |
|
||
ScheduledExecutorService[] execs = new ScheduledExecutorService[count]; | ||
for (int i = 0; i < count; i++) { | ||
execs[i] = Executors.newScheduledThreadPool(count, THREAD_FACTORY); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
count
should be replaced with 1
to guarantee FIFO. Right?
Right, I'll fix them shortly. |
3252de0
to
c36456a
Compare
Updated. |
👍 |
1 similar comment
👍 |
1.x: fix ExecutorScheduler and GenericScheduledExecutorService reorder bug
This PR relates to the failure of
errorThrownIssue1685
.The underlying problem was with the
GenericScheduledExecutorService
. By being multi-threaded, tasks scheduled from the same thread one after the other may get reordered because different worker threads inside the pool could pick them up at the same time. In this case, there is no guarantee they keep their FIFO order.(I currently have no idea how one can use trampolining for this case; subsequent tasks may have any relative delays in respect to each other.)
The solution creates N single threaded
ScheduledExecutorService
s and getInstance() hands one of them out. In turnExecutorService
takes one in its worker upfront.However, there is still the problem when the programmer uses a multi-threaded
ScheduledExecutorService
withSchedulers.from()
when the same issue comes back. A solution to that problem would be to always use the newGenericScheduledExecutorService
for delaying timed tasks.