VSTech
VSTech

Reputation: 77

How to implement executor service by passing new thread as parameter to execute?

I needed to refactor a code to see if it can help me resolve my "Could not open Hibernate Session for transaction". I am currently trying to streamline the way threads are handled in the code.

The existing code is seen as below. Lets call it 'code A':

    if (!CollectionUtils.isEmpty(dailyReportProjectList)) {
            for (ProjectEntity project : dailyReportProjectList) {
                Thread.sleep(2000);
                new Thread(() -> {
                    try {
                        // Implementation Logic

                        if (isConfig == true) {
                            // Generating Daily Report
                        
                            if (dailyRep != null) {
                                LOG.info(
                                        "============start of daily report mail for zone : " + zone + ", newZone : "
                                                + newZone + " for date : " + currOrPrevDay + "===============");
                                new Thread(() -> {
                                    try {
                                        //genericController;
                                        
                                    } catch (Exception e) {
                                        e.printStackTrace();
                                        
                                        }
                                    }
                                }).start();
                            }
                        } else {
                                 //"All 4 default reports for site : " + project.getId() + ", empId:" + project.getEmployerId());
                            
                                }
                            }
                        }
                        LOG.info("End of generateReportByZone >> zone : " + zone);
                    } catch (Exception e2) {
                        e2.printStackTrace();
                        }
                    }
                }).start();
            }
        }
        

In order to streamline this I decided to proceed with Executor Service. I referred a few examples and I am confused as to use service.submit() or service.execute(). I am not seeing my intented benefit from the below code. Can you please help me identify any issues with this apporach.

EDIT: Based on the comments, I have simplified the existing code as above. There is a thread called inside the thread which I feel is not achieving much. Is this ok to have such implementation.

I am planning to do the following:

  1. Instead of passing thread, as a parameter in the for loop, make a separate class and have it implement runnable.

      public class ReportProcessor implements Runnable {
      private int id;
      public ReportProcessor (int id){
       this.id = id;
       }
    
       public void run(){
       try {
      String currOrPrevDay = new String();
      ...// write the code in the try element of 'code A' here onwards
    
  2. In the 'code A' executor. submit the newly created class

                 for (i = 0; i < dailyReportProjectList.length; i ++){
             service.submit(new ReportProcessor(i));
    
             }
    

But how do I fulfil the dependencies required by the existing stated 'code A' if I separate out the logic to a new class. I am trying to model my executor service on the basis of this tutorial https://www.youtube.com/watch?v=KUdro0G1BV4&t=325s

Upvotes: 2

Views: 2432

Answers (1)

terrasson marc
terrasson marc

Reputation: 107

Do not pass a Thread, pass a lambda or anything "runnable".

        ExecutorService service = Executors.newFixedThreadPool(3);

        for (int i = 0; i < 10; i++) {
            final int number = i;
            service.execute(() -> System.out.println("test" + number));
        }

Edit:
I really think this code need simplicity. It seems you want to create reports.
So why create a thread in a Thread ?
And why Thread.sleep ? (generally malpractice, prefer wait/notify)

I do really think you don't need threads at all.
But if you really want (or need) them, loose coupling:

  • Each thread make a single, precise task.
  • Tests to decide what to do have to be upstream.

And try Streams and functional interfaces. It will simplify your code.

dailyReportProjectList.parallelStream()
    .filter(condition)
    .forEach(doSomething)

Streams manage threading themselves.

Upvotes: 2

Related Questions