Java Routine Inside Loop Repeat

Asked

Viewed 318 times

0

I have a Java method that sends an email with an attached doc, and is working properly. But this method takes about 50 seconds running the entire sending process. But now I will need to run it several times in sequence. How can I make this method run, but let it only start again when it finishes?

Example:

while(diretorio!=""){

  enviaEmail(destinatario,assunto,anexo) // isso leva 50segundos executando, mas eu quero que só execute novamente após o término de cada envio..

  }
//o que está acontecendo é que ele está enviando um em cima do outro, sem aguardar cada envio ser concluido

OBS. if the solution is with Threads, where I place the Thread?

2 answers

3


Depending on your need, I see at least two possibilities.

Timer

If you want to perform a process repeat times, but without interleaving the executions, that is, always leaving an interval between one and the other, you can use Timer to schedule such execution.

There are several related questions here at Sopt that can help you:

Queue

If all you want is to queue the uploads so that they are not all executed at the same time, you can create a queue to put data of the messages to be sent.

So create a thread to consume queue items by sending emails one by one, or batch by batch as you prefer. The exact implementation depends on the result you aim for.

In terms of class, it would be interesting for you to look at how to implement a Queue (e. g.: LinkedList) or a deck (e. g.: ArrayDeque).

In case you use different threads to access the file, you need a concurrent implementation, such as LinkedBlockingQueue.

In this case, the thread can be created anywhere as long as you have access to the queue. Example of implementation:

public class GerenciadorEnvio implements Runnable {

    private BlockingQueue<Mensagem> queue = new LinkedBlockingQueue<>();

    public void enviarMensagem(Mensagem m) {
        //coloca uma mensagem na fila
        queue.add(m);
    }

    @Override
    public void run() {
        //laço infinito - uma condição de parada pode ser adicionada
        for (;;) {
            try {
                //Retira um item da fila, se não houver, a thread fica bloqueada aguardando
                Mensagem item = queue.take();
                //enviar e-mail(s) 
            } catch (Exception e) {
                //logar erro
            }
        }
    }

}

The class Mensagem here is just an example that should contain all the information needed to send an email or a group of emails.

Example of use:

GerenciadorEnvio ge = new GerenciadorEnvio();
new Thread(ge).start();
ge.postarMensagem(new Mensagem(...));

In this case, you can send as many messages as you like. If there are no messages, the thread in the method run will be waiting, blocked by the method take.

When a new message is added to the queue, the thread will be unlocked and run the snippet that sends the email.

After finishing the process, the loop goes back to the beginning and checks if there are more messages to be sent. If not, the thread awaits, in positive case she picks up the next message and processes.

-1

First of all it would be interesting to make sure that your approach is in fact the best for this situation, is it necessary to send the same email 50 times? Isn’t it easier (and less costly) to send a single email to 50 different addresses via a hidden copy, so each address would receive as if it were the only one? If you decide to do this through Threads (and send 50 emails...) then a new Thread is created within the loop, where you are calling the method of sending emails.

  • 1

    Hello William, I need to send several emails to different recipients and each associated with a different attached file. I have a folder with attachments and I need to do it daily, in this folder will be recorded the files that I have to send by email, my idea is to scan this folder with that sending method and to each send delete from the folder the file that was sent, and when it’s empty the loop ends...

Browser other questions tagged

You are not signed in. Login or sign up in order to post.