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() 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.
Related
Let's say that i have 10 active threads and only 3 resources (of something)
while the first three threads got the resources i want all other thread that try to get the resource to wait but that the wake up or notify will be in f.i.f.o order i mean that the first thread that got the waiting will be the first to wake up.
thank you all.
I think this link explains it quite well: https://www.safaribooksonline.com/library/view/java-threads-second/1565924185/ch04s03.html
When using notify it is impossible to decide or determine in advance which thread will be allowed to execute. I see 2 solutions to this:
Use notifyAll() and let each thread check for itself whether whose turn it is (e.g. by using a synchronised FIFO queue)
Use the method described in the link: let each thread wait on a different object and use 1 thread that has as it's sole purpose to notify the correct object. This seems like the best solution to me.
Java generally doesn't decide these things however if you use a fair lock e.g.
Lock lock = new ReentrantLock(true);
then those threads will acquire the lock in the order they were attempted. This works by disregarding the order thread would be notified and ensuring a lock which is not taken unless the thread is next on the FIFO queue.
I have a Queue of request. There are two threads. In on thread i am adding the items to queue and second thread basically get the requests from queue list and execute them. So second thread wait for 1st thread to put some request in the list. I am doing so in a while loop. I don't think this is a best way to do it. It is CPU intensive. I can think of a way to notify the 2nd thread whenever I add a request. but there can be problem that the request may not execute successfully so I have to ask 2nd thread again to execute the request.
so is there any way you can think will work ?
Use one of the available blocking queues in Java: http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/BlockingQueue.html
The busy waiting is indeed not recommended (unless you want to use your computer for heating).
You can make use of Semaphores to solve this problem.
The second thread, which is the worker thread will wait on the semaphore. Every time the 1st thread pushes new task info onto the Queue structure, it will also post to the Semaphore so now the second thread can safely go and execute.
This may also need some synchronization along the way if there are multiple reader/writer threads.
In Java, is there a way for a thread to know it has been "interleaved"?
I would like to send a certain update to my clients (who are handled by individual threads) after their thread has been interleaved by another thread.
In case my use of the term "interleaved" is incorrect, I'm referring to the process where the processor stops running one thread and moves to another one.
So when the processor eventually returns to my thread, I would like a certain update to be sent to my client via the thread.
Apparently there is no simple way to detect that a thread has been interleaved.
Instead, I decided to use an atomic integer to track the amount of updates that were executed by all threads.
I then changed the code within my threads to monitor the amount of changes that had been done (since last notifying the client) and, once a certain threshold had been exceeded, I updated the client.
I was trying to read the implementation of Synchronous Queue
It is not so straightforward for me. It seems to be using a linked list where each node is associated with a thread.
And the core part uses a spin loop waiting for tasks to be placed in the queue.
I was wondering why is a spin loop being used instead of something like wait/notify?
Now this way one of the cores is gone due to this constant spin loop, right?
I am trying to understand this point and get a rough understanding of the design of the Synchronous Queue
UPDATE
What is also troubling me is how the waiter threads start/stop.
The point of the SynchronousQueue is to synchronize something which is usually quite asynchronous - one thread placing an item into the queue while another tries to take from it.
The SynchronousQueue is actually not a queue at all. It has no capacity, no internal storage. It only allows taking from the queue when another process is currently trying to put in the queue.
Example:
Process A tries to put in the queue. This blocks for now.
Process B tries to take from the queue. Since someone is trying to put, the item is transferred from A to B, and both are unblocked.
Process B tries to take from the queue, but no one tries to put. So B is now blocked.
Process A now wants to put an item. Now the item is transferred over to B, and A and B are no longer blocked.
About the blocking:
The Sun/Oracle JRE implementation does use polling instead of a wait/notify pattern if you do a timed operation (like "try to take for 1 second"). This makes sense: it periodically retries until the time is up. When you do a non-timed operation (like "take, no matter how long it takes" it does use park, which wakes again if the situation has changed. In neither situation would one of your cores be constantly busy spinning a loop. The for (;;) means "retry indefinately" in this case, it does not mean "constant spinning".
I'm working on a project where execution time is critical. In one of the algorithms I have, I need to save some data into a database.
What I did is call a method that does that. It fires a new thread every time it's called. I faced a runoutofmemory problem since the loaded threads are more than 20,000 ...
My question now is, I want to start only one thread, when the method is called, it adds the job into a queue and notifies the thread, it sleeps when no jobs are available and so on. Any design patterns available or examples available online ?
Run, do not walk to your friendly Javadocs and look up ExecutorService, especially Executors.newSingleThreadExecutor().
ExecutorService myXS = Executors.newSingleThreadExecutor();
// then, as needed...
myXS.submit(myRunnable);
And it will handle the rest.
Yes, you want a worker thread or thread pool pattern.
http://en.wikipedia.org/wiki/Thread_pool_pattern
See http://www.ibm.com/developerworks/library/j-jtp0730/index.html for Java examples
I believe the pattern you're looking for is called producer-consumer. In Java, you can use the blocking methods on a BlockingQueue to pass tasks from the producers (that create the jobs) to the consumer (the single worker thread). This will make the worker thread automatically sleep when no jobs are available in the queue, and wake up when one is added. The concurrent collections should also handle using multiple worker threads.
Are you looking for java.util.concurrent.Executor?
That said, if you have 20000 concurrent inserts into the database, using a thread pool will probably not save you: If the database can't keep up, the queue will get longer and longer, until you run out of memory again. Also, note that an executors queue is volatile, i.e. if the server crashes, the data in it will be gone.