0

I have two spring beans. A JmsHandler which receives a Message. This is processed and handed over to a MailHandler which sends a mail. Now I've seen that sometimes messages arrive at the JmsHandler in exact the same time. When entering the sendMail method one of the both isn't processed properly (no mail is sent). So I would expect that's an threading issue.

I've got two possiblities to handle this issue:

a) I set the sendMail method as synchronized. Which means the next execution will be stopped until the first is processed.

public class JmsHandler {

    @Autowired
    private MailHandler mailer;

    public void handleMessage(Message msg) {
        mailer.sendMail(msg.getPayload().toString());
    }

}

@Component
public class MailHandlerImpl implements MailHandler {
    @Override
    public synchronized void sendMail(String message) {
        // do some fancy stuff...
        // do something to mail the message.
    }
}

b) I define the MailHandler to the scope "prototype" and get it using an lookup from the ApplicationContext.

public class JmsHandler {
    @Autowired
    private ApplicationContext ctx;

    public void handleMessage(Message msg) {
        MailHandler mailer = ctx.getBean(MailHandler.class)
        mailer.sendMail(msg.getPayload().toString());
    }

}

@Component
@Scope("prototype")
public class MailHandlerImpl implements MailHandler {
    @Override
    public void sendMail(String message) {
        // do some fancy stuff...
        // do something to mail the message.
    }
}

I think both ways are ok. But in terms of performance is there any issue? When using synchronized it will stop execution of the next process and wait until the first is finished. The second will create a new Instance of MailHandlerImpl when a message has to be send (and of course autowire other things not shown here). Or is there a third alternative?

meme
  • 81
  • 2
  • 12
  • I would never enter sync block and do IO stuff which could lead to a deadlock. – SMA Jan 21 '16 at 08:32
  • the _sending_ of the mail within `sendMail` is a webservice call to a provider. It's no really IO. ;) – meme Jan 21 '16 at 08:34

1 Answers1

0

The only way to spot performance issue is to get a metrics about your application behaviour. You should see metrics and better use Timer so that you can see how many message has been handled and how fast it is processed. It's awesome.

If you are certain that mail handler is only capable of sending an email in certain moment, just make sure you only have one consumer. No need to use synchronized. If you prefer concurrent process/ multi consumer, which is generally preferred, create mail handler for each thread. Leverage reactor to ease your parallel processing (use thread pool executor in your event bus) and commons pool to hold your mail handler instances. Thread pool executor size and your mail handler pool size should be equal. Or, you can use email service such as mailgun to ease your concurrent email sending.