aspose file tools*
The moose likes Threads and Synchronization and the fly likes Thread sync issue Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Threads and Synchronization
Bookmark "Thread sync issue" Watch "Thread sync issue" New topic
Author

Thread sync issue

Abhishek Rath
Ranch Hand

Joined: Nov 22, 2007
Posts: 38
Hi

I have a application where one class is calling EmailSender class to send the email.In the EmailSender class using taskExecutor and JavaMailSender (spring) to send the email.Here it is creating a new thread.
This thread is still executing the email sending task in background however the control goes back to the calling calass and it updated the databaseassuming the email is successful.

However the thread sending email throws exception after some time.

So we have two thread one sending the email and another one updating the DB.The DB update thread with is the main thread should wait till the email sending thread gest completed.

My question is that how to me this happen.

Regards
Abhishek Rath
Nomaan Butt
Ranch Hand

Joined: Oct 19, 2011
Posts: 54
as far as i understood you want that DB should be updated after mail is sent successfully, if that is the case than it can be solved using semaphores. Here i have used a semaphore and two inner classes one for sending mail and one for updating DB. Its just one solution there can be more.

public class MailHelper{

final Semaphore semaphore = new Semaphore(1);
boolean updateDB = false;

public static void main(String args[]){

new Thread(new EmailSender()).start();
new Thread(new DBUpdater()).start();
}
class EmailSender implemets Runnable{

public void run(){

semaphore.acquire();
some code to send the mail...
updateDB=true;
semaphore.release()

}
}

class DBUpdater implemets Runnable(){

public void run(){

if(updateDB){
semaphore.acquire();
some code to update the DB...
semaphore.release();
}


}

}
}
Jayesh A Lalwani
Bartender

Joined: Jan 17, 2008
Posts: 2372
    
  28

First of all, why don't you update DB in the same thread as the EmailSender? Why are you sending email in the background? Are you sending a heavy volume of emails using a thread pool and updating DB after the emails have been sent?


Are you using ThreadPoolExecutor? From the main thread, you can call shutdown on ThreadPoolExecutor and then awaitTermination to wait for all the tasks in the executor to finish.
Abhishek Rath
Ranch Hand

Joined: Nov 22, 2007
Posts: 38
Hi All

The class(EmailSender.java) which is sending the email has the below code in sendEmail Method

TaskExecutor.execute(new Runnable() {public void run() {
MailSender.send(new MimeMessagePreparator() {public void prepare(MimeMessage mimeMessage)throws MessagingException {
MimeMessageHelper message = new MimeMessageHelper(mimeMessage, true);

This sendEmail method is invoked from SendEmailActivity class

emailsender.sendEmail();

The next line in SendEmailActivity class is to update the DB by calling an DAO class.


-
Abhishek Rath
Ranch Hand

Joined: Nov 22, 2007
Posts: 38
Hi Nomman

I can not change the structure of the class.It an existing running code and changing the structure i.e. adding new inner class will be difficult.

Regards
Abhishek Rath
Ranganathan Kaliyur Mannar
Bartender

Joined: Oct 16, 2003
Posts: 1083
    
  10

Nomaan,
Please UseCodeTags to post code.


Ranga.
SCJP 1.4, OCMJEA/SCEA 5.0.
Ranganathan Kaliyur Mannar
Bartender

Joined: Oct 16, 2003
Posts: 1083
    
  10

Abhishek,
Nomaan was just showing an example. It need not be an inner class.
You have mentioned Executor, so I believe you would be implementing Runnable. If so, you can use the semaphore from inside the methods- basically, the semaphore object needs to be accessed by both classes/methods, so an inner class was shown here.
If that is not possible, you will have to find your own mechanism. Note that Semaphore is just like any other Java object, so you might provide a public getter method and use it from both threads.
If not, you can use the wait(), notify() methods to achieve what you are trying to.
Jayesh A Lalwani
Bartender

Joined: Jan 17, 2008
Posts: 2372
    
  28


If you cannot change the runnable, you can wrap it.. You can do soemthing like this



ETA: Actually, you might want to a little more complicated than that. In your main thread, you really want to acquire the semaphore after your Runnable starts executing. However, you have no idea when the TaskExecutor is going to execute it. You might have other Runnables in the queue before you. It's unfortunate that Spring didn't add support for Future until Spring 3. If you don't have support for Callable, you will have to build your own signalling mechanism to communicate between the 2 threads. If it supports Callable, wrap your runnable into a callable that returns a boolean or something. The main thread can call get on the Future object it recieves. get will wait till your Runnable has finished execution

Also, you might want to think about what happens when your Runnable throws exception. Wouldn;t you want to indicate something in the database that the message isn't sent?
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Thread sync issue