-3
BlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(100, true);
RejectedExecutionHandler handler = new ThreadPoolExecutor.CallerRunsPolicy();
ExecutorService executor = new ThreadPoolExecutor(4, 10, 0L, TimeUnit.MILLISECONDS, queue,handler);

executor.execute(new Runnable() {
                        @Override
                        public void run() {
                        for(looping arraylist){
                           operations related to calling proc...
                         }
                     }
                   });

executor.shutdown();
        while (executor.isTerminated() == false){
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

The performance of the above code is way too slow, it takes 7minutes to complete the entire operation and get the data.

I am trying get large data from 2 stored procedures. To increase the speed I am using multithreading.

Can someone please provide solution to increase the performance to large extent.

  • What is your goal? What are you trying to accomplish by specifying a queue and handler? Why not use a regular executor service provided by `Executors` utility class? – Basil Bourque Sep 16 '21 at 19:08
  • @BasilBourque Most methods in `Executors` return a `ThreadPoolExecutor` anyway (except for the few that return a `ForkJoinPool`). – Slaw Sep 16 '21 at 19:20
  • 1
    @Rohan Your code does not seem complete, but if what you do show is accurate then you only submit one task. You then immediately shutdown the pool and wait for it to terminate. In other words, you may as well be executing the task in the current thread (i..e. synchronously). If you want tasks to run concurrently then you need to submit each task to the executor separately. Also, don't wait for the executor to terminate via a while loop; use the `awaitTermination(long,TimeUnit)` method instead. – Slaw Sep 16 '21 at 19:24
  • @Rohan Maybe changing `== false` to `!` can have a small difference https://softwareengineering.stackexchange.com/a/136956/402123 – Costa Sep 17 '21 at 09:42
  • Please clarify your specific problem or provide additional details to highlight exactly what you need. As it's currently written, it's hard to tell exactly what you're asking. – Community Sep 23 '21 at 20:06

1 Answers1

1

Your question lacks details. But I will try to guess.

'ThreadPoolExecutor' manages pool of threads. When you submit task, it will use free thread to run task.

So, if you are immediately submit 20 tasks, only 4 will be processed concurrently (in your example max threads = 4*). And when one of the task will be finished, next will be processed.

And now look at your code - only one executor.execute(new Runnable(). So, only one task submitted.

May be you want smth like code below:


for(looping arraylist){
    executor.execute(new Runnable() {
                        @Override
                        public void run() {
                           operations related to calling proc...
                     }
    });
}

*4 threads until queue not full (100 waiting tasks in your code). After 104 submitted, new threads will be used (up to 10 at your code). Thanks 'Slaw', see his comment.

Timur Efimov
  • 358
  • 2
  • 10
  • 1
    "_So, if you are immediately submit 20 tasks, only 10 will be processed concurrently (in your example max threads = 10)_" – If I'm not mistaken, likely only 4 tasks will execute concurrently because a `ThreadPoolExecutor` only creates more threads beyond the core count if the queue reaches max capacity. So unless the OP is immediately enqueuing > 100 tasks I believe only the core threads will be executing tasks. – Slaw Sep 16 '21 at 19:18
  • Yes! Sorry. Thank you, I will edit my answer. – Timur Efimov Sep 16 '21 at 19:25