views:

45

answers:

1

Hi,

Are ThreadPoolExecutor and ScheduledThreadPoolExecutor thread-safe?? Now, I have a scenario as under:

  • 5 ThreadPoolExecutor(s)
  • exec1 (which executes JobA (Job of Level A) : parallelism of 4-5 jobs max),
  • exec2 (which executes JobB (made from List inside each JobA) : over 800-3000 jobs per JobA),
  • exec3 (which executes and prepares JobC (made from each JobB) : 2-3 jobs per each JobB)),
  • exec4 (which executes JobD (1-2 activites per Job)),
  • exec5 (which waits for all jobs to be completed and then executes certain activities);

(I hope the above scenario is clear).

Further, all executors are common at the object level. At level A, there are only max 4-5 jobs executing in parallel and preparing for the next level (B) various individual jobs / transactions. Jobs of Level B in turn prepare jobs for level C and Level C prepares jobs for Level D.

Exec5 is a persistor which persists all the data to a DB.

The issue is that jobs are getting lost somewhere at Level C & D i.e., especially when there are many simultaneous threads trying to push newer jobs in subsequent executors task lists asynchronously. None of the RejectionHandlers also received any rejected handlers. Also, I dont face any issues if each of the ThreadPoolExecutors is reduced to a single thread pool executor (1 Thread only). The jobs are inherently very small and hence the parallelism does offer a significant advantage to the activity.

I hope I have been clear.

Please advise. Regards, KT

+2  A: 

How are you submitting work to your ExecutorService's? Are you using submit(Callable) or execute(Runnable)? In the former case it is the calling code's responsibility to detect any exceptional conditions by calling get() on the returned Future. Hence if your executors are simply passing work to the next executor and discarding the Future any errors will go undetected.

One workaround is to use execute(Runnable) and override ThreadPoolExecutor's afterExecute(Runnable r, Throwable t) method to raise an alert if called with a non-null Throwable.

An alternative solution would be to wrap the executor in a CompletionService and have a dedicated thread remove completed Futures and "extract" and exceptions.

As an aside this architecture seems quite complicated. Are 5 levels of executor really necessary? Why not start with a single ThreadPoolExecutor that carries out all the required steps? The simpler your design the easier it will be to detect any problems.

Adamski
Thanks for the reply.However, a single ThreadPoolExecutor would not really suffice. The idea is that only after a Level 2 job is completed a corresponding Level 3 job is required to be handled. Further, there are periodic checks to ensure release of resources after completion of each level-The most critical being level 2 also, the separate Executors give an exact status of tasks pending at each stage rather than keeping a track of it separately; task wise thread Priority setting is easier rather than setting priorities per job.Shall try the afterExecute suggestion to debug the issue.
Kapil
When a Level 2 job completes why can't it submit a bunch of level 3 jobs to the same executor? If you need to wait for all level 2 jobs to complete before submitting level 3 jobs then why not submit level 2 jobs to a completion service (wrapping the executor) and then poll until all level 2 jobs have completed. At this point you could submit your level 3 jobs.
Adamski
Code clarity and definition of purpose of every object. Simply because I can resubmit to the same scheduler does not mean that I should submit to the same executor.With a clear purpose defined for every executor (representing a logical step completion), it becomes easier to manage. In fact, had this not been done, probably the debugging would have been far more difficult as well. Also, as explained above,there are other factors like thread priority settings and shutdown hooks attachment, etc., which makes the code logical and clean. Anyway, that is not something that would affect the resuls.
Kapil
Sorry, on plain reading of the comment, it sounded rude. Didnt mean to... Apologising for any such unintentional feeling but some words were edited due to space contraint in comments.Regards,KT
Kapil
Don't worry; no offence taken!
Adamski