I have a method that will be used to send out email. i want to lock this method so only one thread can accses it per time and the rest pool up concurrently. should i synchronized the method or use spring #transactional PROPAGATION_REQUIRED ?
in my service layer
//each time use new thread to send out email
public void sendThroughSMTP(List<String> emails,String subject,String content){
//each time will open and sent through port 25. dont u think this will caused too many threads spawned?
BlastEmailThread blastEmailThread = new BlastEmailThread(emails,subject,content);
blastEmailThread.start();
}
Why not make the method thread-safe by not using any instance level things?
However, I don't see how Spring's Transaction Management fits here. I mean Spring provides few transaction managers, i.e. DataSourceTransactionManager, JtaTransactionManager, HibernateTransactionManager all this is about database persistence. What will you configure for this email send out?
I believe, first you should show us why you worry about the thread-safety in the first place. Most probably you would like to show us some relevant code snippet or something. Then we might be able to suggest you something.
[Addendum]
When you are spawning a thread for every call to that method and not using anything from the state, then why you want to make the method synchronized. Making the method synchronized will not limit the number of threads in any way. There might be chance that before starting a new thread, previous thread might have finished the work, because of synchronization. The process of spawning a thread might go slower.
However, you should go with this until you find out that there are really many threads running and you are going out of memory. And if you really want to tackle that before time, then you should choose some blocking mechanism, something like Semaphore.
I'm not sure if it answers your question, but instead of creating a new thread for every mail and calling start on it you could have an Executor or ExecutorService as a member of your class, as an implementation you could use a ThreadPoolExecutor with a pool size of 1. Your sendMail method would then submit Runnables to the executor.
Another possibility would be to use JMS queues and put the email sending code in a Message Driven Bean (or through Spring JMS). You can then use your app server to control how many concurrent instances of your MDB will be used and throttle the outgoing emails that way.
in Sping 3.0 you can use #Async annotation to do task execution, so your method will be executed later and the method is returned directly without waiting for email to be sent.
#Async
public void sendThroughSMTP(List<String> emails,String subject,String content){
//Send emails here, you can directly send lots of email
}
then in application context you specify and don't forget to add xmlns for task schema.
If you want to delay the execution for certain amount of time, you may use #Scheduled annotation to your method.
Further tutorial about #Async and #Scheduled can be found here :
http://blog.springsource.com/2010/01/05/task-scheduling-simplifications-in-spring-3-0/
Make your service a singleton and add synchronized to your method.
Spring #Transactional is not quite correct used in your case. The best bet is using synchorized method and add some thread pooling if your method called by hundreds time. But i guess you dont need thread pool here.
If you use thread to send blast email, then what's point synchronizing the method? if one process call your method and send email, other process will call you method even the first sending email process not yet finish.
If you intent to throttle the email sending process, you need to condider a queue (collection) and protect the collection with synchronize block. Create another process to monitor that queue, if there is one item in queue, pop it and send blast email, then wait until sending email process finish and check again the queue, if there is any item, continue to sending email process. If no item in the queue, make the monitor thread sleep for some chunk of time, then if sleep time is finish check the queue again.
Related
I'm trying to understand how to deal with threads within a Java client that connects to HornetQ. I'm not getting a specific error but fail to understand how I'm expected to deal with threads in the first place (with respect to the HornetQ client and specifically MessageHandler.onMessage() -- threads in general are no problem to me).
In case this is relevant: I'm using 'org.hornetq:hornetq-server:2.4.7.Final' to run the server embedded into my application. I don't intend this to make a difference. In my situation, that's just more convenient from an ops perspective than running a standalone server process.
What I did so far:
create an embedded server: new EmbeddedHornetQ(),
.setConfiguration()
create a server locator: HornetQClient.createServerLocator(false, new TransportConfiguration(InVMConnectorFactory.class.getName()))
create a session factory: serverLocator.createSessionFactory()
Now it seems obvious to me that I can create a session using hornetqClientSessionFactory.createSession(), create a producer and consumer for that session, and deal with messages within a single thread using .send() and .receive().
But I also discovered consumer.setMessageHandler(), and this tells me that I didn't understand threading in the client at all. I tried to use it, but then the consumer calls messageHandler.onMessage() in two threads that are distinct from the one that created the session. This seems to match my impression from looking at the code -- the HornetQ client uses a thread pool to dispatch messages.
This leaves me confused. The javadocs say that the session is a "single-thread object", and the code agrees -- no obvious synchronization going on there. But with onMessage() being called in multiple threads, message.acknowledge() is also called in multiple threads, and that one just delegates to the session.
How is this supposed to work? How would a scenario look in which MessageHandler does NOT access the session from multiple threads?
Going further, how would I send follow-up messages from within onMessage()? I'm using HornetQ for a persistent "to-do" work queue, so sending follow-up messages is a typical use case for me. But again, within onMessage(), I'm in the wrong thread for accessing the session.
Note that I would be okay with staying away from MessageHandler and just using send() / receive() in a way that allows me to control threading. But I'm convinced that I don't understand the whole situation at all, and that combined with multi-threading is just asking for trouble.
I can answer part of your question, although I hope you've already fixed the issue by now.
Form the HornetQ documentation on ClientConsumer (Emphasis mine):
A ClientConsumer receives messages from HornetQ queues.
Messages can be consumed synchronously by using the receive() methods which will block until a message is received (or a timeout expires) or asynchronously by setting a MessageHandler.
These 2 types of consumption are exclusive: a ClientConsumer with a MessageHandler set will throw HornetQException if its receive() methods are called.
So you have two choices on handling message reception:
Synchronize the reception yourself
Do not provide a MessageListener to HornetQ
In your own cunsumer Thread, invoke .receive() or .receive(long itmeout) at your leisure
Retrieve the (optional) ClientMessage object returned by the call
Pro: Using the Session you hopefully carry in the Consumer you can forward the message as you see fit
Con: All this message handling will be sequential
Delegate Thread synchronization to HornetQ
Do not invoke .receive() on a Consumer
Provide a MessageListener implementation of onMessage(ClientMessage)
Pro: All the message handling will be concurrent and fast, hassle-free
Con: I do not think it possible to retrieve the Session from this object, as it is not exposed by the interface.
Untested workaround: In my application (which is in-vm like yours), I exposed the underlying, thread-safe QueueConnection as a static variable available application-wide. From your MessageListener, you may invoke QueueSession jmsSession = jmsConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); on it to obtain a new Session and send your messages from it... This is probably alright as far as I can see because the Session object is not really re-created. I also did this because Sessions had a tendency to become stale.
I don't think you should want so much to be in control of your Message execution threads, especially transient Threads that merely forward messages. HornetQ has built-in Thread pools as you guessed, and reuses these objects efficiently.
Also as you know you don't need to be in a single Thread to access an object (like a Queue) so it doesn't matter if the Queue is accessed through multiple Threads, or even through multiple Sessions. You need only make sure a Session is only accesed by one Thread, and this is by design with MessageListener.
So let me start with making the requirement pretty clear
I am creating a Java Server side application which has a couple of REST APIs. Now I want to collect stats and do some logging when the API is invoked via HTTP
Now logging and collecting/persisting stats can slow down the API call so I want this to happen asynchronously so API execution can go ahead.
So what solution would be best for this? I want to make sure that no data is lost and also the solution can scale with load. I thought of Akka framework but not sure it will meet my requirement. Creating simple threads to do the job might not scale. Is there any standard Java solution/pattern for this?
Implement a Thread pool with fixed number of threads(whatever is optimum)
create custom objects that has all the details required w.
have a Queue that can hold these custom objects
Whenever API is called, create these objects and place them in Queue
Threads should wait on the queue, if empty, dequeue these Tasks(custom objects), do the logging asyncronously.
After the job is done, dont kill these threads. have a while() loop inside the thread, so that it can wait again on the queue to dequeue another task and perform it.
I want to generate some text string that is going to be sent via TCP socket . I have accomplished it within few minutes.
However I want a producer consumer pattern.I dont care if it failed or not.
Should I create a Blocking Queque at application for this ? Should I create a service ?
Note that I want a single thread to manage this job.
In the case it's a short task (like you commented), I'd recommend putting it within an AsyncTask as a background thread. You can control anything about this separately, which will help you also debugging it. Services are more intended for long executing tasks, so I'd not recommend it at this scope (it's a bit harder even to communicate with other Activity's. Here you'll find the AsyncTask's documentation, and here a good example.
The Blocking structure depends on your needs - but I don't think you'll need that in your case. Anyway, if you would need that, there're lots of thread-safe data structures you may use, you might find this helpful.
Create a LinkedBlockingQueue where your producer adds data. Create a Timer that fires every second or so. The task of the Timer would be to send the messages over the wire.
For this, both the producer (the one generating the messages) and consumer (Timer) should have access to the LinkedBlockingQueue. The Timer will remove the first element of the LinkedBlockingQueue and then send it.
Sounds good ?
I'm not sure if I'm on the right track, but I have previously created a Thread and stored it in the current session to be able to use it in other Servlets.
When a user logs in, I need a Thread that will periodically poll a webservices server and retrieve updates. When the user logs out I want to stop/pause the Thread.
If I create the Thread when the user logs in, I need a reference to this Thread if I want to pause it when the user is logged out, and then start it again when they login.
What is the best and correct way to go about this? Should I monitor the session from inside the Thread and if the user has logged out, have the thread return in order to end the Thread?
Then next time the user logs in, I can create a new background Thread?
***I need the thread to run in the background and poll a web services server for updates which I use to update my database. It may poll once every 5 minutes.
I don't want it to be polling all the time, hence why I was trying to control it based on the user being logged in or not... I was setting the boolean running to false when they log out in order to stop the thread. Because the thread was stored in the application context, I could then set running to true when they logged back in.
What about a Thread to run in the background and check something, for example that your internet is up?
I know how to create the Thread, but I'm confused about how to terminate it, since it needs to be continually running in the background.
Am I using threads for the wrong thing? should I be using something else?
Thanks again, hopefully this is a better explanation...
Since servlets themselves will be instantiated multiple times at the same time, creating even more threads is not a wise idea. You will run into problems if you decide to cluster your application one day across multiple machines because of serialization issues, so you're locking yourself at the beginning.
Besides, it seems your problem can be done using AJAX pooling from client side. Why pool a webservices server and retrieve updates if you can't show them to your client without them refreshing the entire page?
Think of this scenario: if a user sessions lasts for 30 minutes, and a user doesn't log out, but just closes the browser window: you won't know that this happened, and you would pool for next 30 minutes that webservice, which is a waste of resources.
A Thread is not serializable, so storing it in a session is likely to be problematic.
Also, stopping or pausing a thread can be problematic unless you code the thread's Runnable to periodically check to see if it has been paused / stopped and act accordingly. (The Thread.stop() and Thread.pause() methods are deprecated and you should avoid using them. They can potentially destabilize your JVM.)
Even if you address the above issues, there are a host of resource management issues to be addressed.
I'm not sure if I'm on the right track
In short, you are not, IMO.
You have not explained why you need to associate a thread with each session, or what these threads are intended for. If you did, you would get some good suggestions for alternative approaches that (largely) avoid the problems above.
FOLLOWUP
I wasn't using .stop and .pause.
Good.
i was using a boolean "runnable" to control the thread.
That's one alternative. I prefer to use the Thread.interrupt() mechanism, because it allows you to interrupt a thread that is blocked on an I/O operation or in a wait(...) call to stop.
What if you are polling a device, and need to access returned data? What is the best approach?
Probably, the best approach is to create a thread or thread pool in servlet initialization that is responsible for polling the device(s). If you need to save the returned data so that it can be accessed in a subsequent HTTP request, put it into (say) a queue that the request controller can access. You may need some infrastructure to remove uncollected data objects from the queue after a certain period, etc.
You really shouldn't be creating Threads inside containers at all. What's it for?
And if it's for use by other servlets it's more likely to belong in the application attributes, not the session attributes, isn't it? or are you really creating a thread per user? which you really don't want to do.
I can see, that there may be valid reasons to do the polling server side in a background thread: For example it may take longer than a user wants to wait for the answer of a request. And there is the issue that some anti-discrimination laws (to be more precise the guidelines on how to interpret those laws) deny the use of JavaScript, so no Ajax.
So if there is really no other way, I suggest to create one thread (or a very small thread pool) in Servlet.init(). This single (or small number of threads) should do the polling for all active users. In web.xml you can define a session listener so you can keep track of opened and closed/expired sessions.
Make sure to signal in Servlet.destroy() that the thread(s) should exist.
To define a session live cycle listener add this in web.xml:
<listener>
<listener-class>
com.example.SessionListener
</listener-class>
</listener>
And then remember the open sessions, so that you can iterate over them in the background thread.
public class SessionListener implements HttpSessionListener {
private Set<HttpSession> sessions = Collections.synchronizedCollections(
new HashSet<HttpSession>());
public void sessionCreated(HttpSessionEvent sessionEvent) {
HttpSession session = sessionEvent.getSession();
sessions.add(session;
}
public synchronized void sessionDestroyed(HttpSessionEvent sessionEvent) {
HttpSession session = sessionEvent.getSession();
sessions.remove(session);
}
}
A little help please.
I am designing a stateless server that will have the following functionality:
Client submits a job to the server.
Client is blocked while the server tries to perform the job.
The server will spawn one or multiple threads to perform the job.
The job either finishes, times out or fails.
The appropriate response (based on the outcome) is created, the client is unblocked and the response is handed off to the client.
Here is what I have thought of so far.
Client submits a job to the server.
The server assigns an ID to the job, places the job on a Queue and then places the Client on an another queue (where it will be blocked).
Have a thread pool that will execute the job, fetch the result and appropriately create the response.
Based on ID, pick the client out of the queue (thereby unblocking it), give it the response and send it off.
Steps 1,3,4 seems quite straight forward however any ideas about how to put the client in a queue and then block it. Also, any pointers that would help me design this puppy would be appreciated.
Cheers
Why do you need to block the client? Seems like it would be easier to return (almost) immediately (after performing initial validation, if any) and give client a unique ID for a given job. Client would then be able to either poll using said ID or, perhaps, provide a callback.
Blocking means you're holding on to a socket which obviously limits the upper number of clients you can serve simultaneously. If that's not a concern for your scenario and you absolutely need to block (perhaps you have no control over client code and can't make them poll?), there's little sense in spawning threads to perform the job unless you can actually separate it into parallel tasks. The only "queue" in that case would be the one held by common thread pool. The workflow would basically be:
Create a thread pool (such as ThreadPoolExecutor)
For each client request:
If you have any parts of the job that you can execute in parallel, delegate them to the pool.
And / or do them in the current thread.
Wait until pooled job parts complete (if applicable).
Return results to client.
Shutdown the thread pool.
No IDs are needed per se; though you may need to use some sort of latch for 2.1 / 2.3 above.
Timeouts may be a tad tricky. If you need them to be more or less precise you'll have to keep your main thread (the one that received client request) free from work and have it signal submitted job parts (by flipping a flag) when timeout is reached and return immediately. You'll have to check said flag periodically and terminate your execution once it's flipped; pool will then reclaim the thread.
How are you communicating to the client?
I recommend you create an object to represent each job which holds job parameters and the socket (or other communication mechanism) to reach the client. The thread pool will then send the response to unblock the client at the end of job processing.
The timeouts will be somewhat tricky, and will have hidden gotcha's but the basic design would seem to be to straightforward, write a class that takes a Socket in the constructor. on socket.accept we just do a new socket processing instantiation, with great foresight and planning on scalability or if this is a bench-test-experiment, then the socket processing class just goes to the data processing stuff and when it returns you have some sort of boolean or numeric for the state or something, handy place for null btw, and ether writes the success to the Output Stream from the socket or informs client of a timeout or whatever your business needs are
If you have to have a scalable, effective design for long-running heavy-haulers, go directly to nio ... hand coded one-off solutions like I describe probably won't scale well but would provide fundamental conceptualizing basis for an nio design of code-correct work.
( sorry folks, I think directly in code - design patterns are then applied to the code after it is working. What does not hold up gets reworked then, not before )