简体   繁体   中英

Java Concurrency: Threads notifications

I have a java concurrency problem, it goes like this: There is a Servlet ( serv1 ) that stores objects (representing messages) into a database. There is also a Thread ( t1 ) that looks (in the database) for unsent messages and delivers them. t1 runs every 5 minutes so, for efficiency purposes, serv1 notifies t1 every time it stores a message.

The question is: How the notification process is going to behave on a highly concurred scenario where serv1 is receiving an extremely high amount of requests and thus t1 is being notified so much that it'd simulate a " while (true) "?.

Another question: How does the notification process will behave if serv1 wants to notify t1 but t1 is already awake/running?

Thanks in advance!!

I don't think this is an issue @Wilmer. I suspect that the notification itself is relatively cheap compared to the cost of consuming and processing your messages. If you are spinning consuming then messages then removing the notifications is not going to help the process and you will have to block your serv1 thread somehow or offload the jobs to run later.

In terms of notifications, if no one is waiting then the notify() is effectively a no-op. This is why it is important to check to see if there is anything to process before waiting on the signal -- all in a synchronized block. It is best practice to also loop around the wait and check again when we are notified. See this race condition .

In general, this is a very common practice that is used in virtually all producer/consumer thread models that I have seen. The alternative is not to handle the square wave traffic changes. Either your consumer (t1) is waiting too long and the buffers fill up or it is spinning too much and is consumer too much CPU checking the database.

Another thing to consider is to not use the database but to put the objects into a BlockingQueue for t1 to consume directly. If you need to store them in the database then put the IDs of the objects in the queue for t1 to consume. The thread will still need to poll the database on startup but you will save the polls later in the process.

Why are you notifying t1 at all? Why doesn't T1 on it's 5 minute sweep query the database and process all of the pending messages? Then you don't need a notification at all, you simply use the database.

In order to use Object o = new Object(); o.notify() Object o = new Object(); o.notify() correctly, it has to be done after obtaining that object's monitor (becoming its owner; AKA synchronize on it). Moreover, the awakened thread that waits upon that monitor will have to wait yet again for the notifying thread to release that monitor and try to obtain it. Only then it shall continue processing.

So, when t1 will be awakened, it will actually fight all other serv1 threads for becoming owner of the monitor. It might obtain the monitor, thus stalling all serv1 threads (not good). It might loose constantly to serv1 's threads and not process the accumulating messages in the database (just as bad, I guess).

What you should do, is let the producers ( serv1 threads) work asynchronously with the consumer ( t1 ). t1 should continue to run every X minutes (or seconds) and process all the messages altogether. Another option, if you want to keep the thread in low activity: configure several consumer threads ( t1 , t2 , t3 ... etc.). You can use a Executors.newFixedThreadPool(int nThreads, ThreadFactory threadFactory) for this purpose.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM