0

I have a method sendMail(list). This method will send the mails to the recipients which are there in the list.

public void sendMail(List<DTO> dto) {


        for(DTO individualObject: dto) {
            
            bulkMailSender.sendSimpleMessage(individualObject.getEmail(),masterDetails.getMailSubject() , content, masterDetails.getMailFrom(), individualObject); 
            try {
                TimeUnit.MINUTES.sleep(Long.parseLong(individualObject.getTimegap().trim()));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    }

}

I have this kind of method. I want to run this method Thread based, when one thread is executing the mails, I should allow the other thread to access sendMail and send simultaneously together. Each and every individualObject contains it's own sleep time.

How can I make it worked with the multiple threads.

Let's take an example

import java.util.concurrent.TimeUnit;

public class SleepClass {
    public static void main(String[] args) {
        SleepClass s= new SleepClass();
        s.m1(10000);
        s.m1(20000);
        
        
    }
    
    public void m1(int time) {
        
        for(int i = 0; i< 3; i++) {
            System.out.println(i);
            try {
                Thread.sleep(time);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        
    }

}

In the above example I have a regular method and it is executing one by one. How can make it simultaneous execution

Jeb
  • 447
  • 2
  • 6
  • 13
  • 1
    Note that `if(!dto.isEmpty())` is unnecessary, because the enhanced `for` loop here already implies that. – MC Emperor Sep 30 '20 at 09:49
  • Regarding your question – what exactly is the issue you are facing? Is there something not working? Do you encounter exceptions thrown? – MC Emperor Sep 30 '20 at 09:52
  • I don't understand your problem. Just call `sendMail` from different threads and it will be executed in parallel. – Henry Sep 30 '20 at 09:52
  • @Henry Ok my issue is if we know how many threads are going to access my application then I can call directly with `Thread t1 = new Thread(new MagicTask());` t1.start();. If we dont know how to call that method with different threads? – Jeb Sep 30 '20 at 09:54
  • 1
    every application that wants to access this method will create a new thread. So you don't have to instantiate threads upfront. If you want to limit the number of parallel threads you need to setup a queue and a threadpool. – Conffusion Sep 30 '20 at 10:06
  • @Conffusion you mean if two requests comes to my method then it will execute both simultaneously? – Jeb Sep 30 '20 at 10:11
  • yes, and the success of it will depend also on how thread safe `bulkMailSender` is because it is instantiated outside your method so can potentially be shared by .multiple threads. – Conffusion Sep 30 '20 at 10:13
  • @Conffusion I have updated the example in my question. Please look into that that is executing one by one not simultaneously – Jeb Sep 30 '20 at 10:17

2 Answers2

1

You have to put your logic in a Runnable and launch it using new Thread(runnable).start(). To pass parameters to each runnable define them as class variables so you can pass them via the constructor and use them in the run method:

public class SleepClass {

    public static void main(String[] args) {
        SleepClass s= new SleepClass();
        s.m1(10000);
        s.m1(20000);
    }
    
    public void m1(int time) {
        for(int i = 0; i< 3; i++) {
            new Thread(new Launcher(i,time)).start();
        }
    }

    public class Launcher implements Runnable {
        int i;
        int time;
        public Launcher(int i, int time) {
            this.i=i;
            this.time=time;
        }
        @Override
        public void run() {
            System.out.println(i);
            try {
                Thread.sleep(time);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }                   
        }
        
    }
}
Conffusion
  • 4,335
  • 2
  • 16
  • 28
  • This program also printing the same `01230123` is the output, means it is not executing simultaneously – Jeb Sep 30 '20 at 10:58
  • That is not possible as it will only print from 0 to 2. My output was: 0,2,1,1,0,2. And the second time: 0,2,1,0,1,2 – Conffusion Sep 30 '20 at 11:47
1

if you need simultaneous execution and each time new thread you can find the solution here

public class SleepClass {
    public static void main(String[] args) {
        SleepClass s= new SleepClass();
        s.m2(500);
        s.m2(1000);
    }
    
    public void m2(int time) {
        SleepClass s= new SleepClass();
        new Thread(() -> {
            s.m1(time);
        }).start();
    }
    
    public void m1(int time) {
        
        for(int i = 0; i<= 10; i++) {
            System.out.println(i);
            try {
                Thread.sleep(time);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        
    }

}
Gen
  • 2,400
  • 4
  • 24
  • 46