I came across Java: notify() vs. notifyAll() all over again but still could not satisy myself.
xagyg explained it very well but in the end it became very complex to memorize the concept.
I am trying my best here with simple daily life example so that i and others can come back to this if any one forget. My source of understanding
is answer by xagyg in above link but trying to simplyfy the things here.
Say two guys go to movie theatre and found its houseful. But then box office guy say Jon told them there is a ticket that has been
reserved for president. If he does not come, he will sell it off. Then guys told to jon, ok we are waiting in hotel near by, please
notify us when you get any info. These guys go to hotel and sleep. Now president does not turn up, now Jon has two options
First is notify one of the guy and let other sleep. If he does that one can go movie while other will probably continue to sleep(till
he doesn't get notified. I am assuming this guy didn't have sleep for a year :)). Another option is he notifies(awakens) both of them,
choose any one of them(In actual java example program does not select but its vm/thread scheduler) for movie.In that case he will keep other guy in hotel room as he can create some kind of issues :(. Now once
the show ends, this guy can go for next show if ticket is available. Consider ticket as lock, theatre as object. This what exactly
notify and notifyAll does. So it is clear that notifAll is better over notify when in confusion
Now consider producer/consumer example.
say two consumer thread are waiting for production in store. Now what producer does, he produces two items in single go and exit. Now if producer use notify, only one thread can consumer while other will continue to wait for forever.
But if producer uses notifyAll() here, both thread can go for consumption one at a time
Let me know if my understanding is correct?
I don't think what you've written in the last statement is correct. Each time the producer produces an object it is supposed to notify a consumer, so if 2 objects are created it should invoke notify twice and not just once. This way if you use notify instead of notifyAll, you will still be able to get both consumer threads to consume
Related
Scenario
There is a factory that receives orders. Once received, every order item goes through a multi-step production process. Every step is done by a separate machine and every machine can only handle one item at a time. So the order comes in, the first item goes to machine1, when it's done it goes to machine2 and the next item to machine1, etc.
Technical part
Every machine is implemented as a thread and has a queue with all items lined up that need this step of the process next. The run method of the machine checks in an endless while loop if there is anything in the queue, if yes it will handle that item, sleep for a certain amount of time and then push the item to the queue of the next machine.
Questions
In my head, this sounds all pretty simple. But I constantly run into null-pointer errors and other weird exceptions. I honestly don't fully understand what's wrong but I suspect it's a problem with multi-threading vs. sleep. At this point I got two questions:
What happens if I call a method of a sleeping thread (machine)? (Example: I call machine.addItemToQueue() while that machine is working on another item).
Follows Q1: Let's say I really can't call that method while the machine 'sleeps'. How else would I handle this? Should I take the queue outside the machine? Is this an async problem?
I'm facing a problem. I have a Java client-server application that manages a restaurant; I need to use just keyboard input and output in order to manage it.
My waiter class has two threads: one that reads orders from the input, and one that is continuatively listening (using multicast) for a ready dish that needs to be delivered to the table.
Considering that everything is meant to be done with keyboard, my "ordering" thread writes to standard output "Do you wanna make an order? [y/n]" and waits for an answer, while the "delivery" thread listens for something to be delivered.
If the waiter chooses to order something, then the second thread doesn't show anything until the order is finished (done using a status boolean); if the waiter is free (which means, is showing the hint: "Do you wanna order?") and a ready dish arrives he will see on standard input "There is something to be delivered. Wanna deliver it? [y/n]" and wait for an answer.
My problem is that, whatever he chooses, I don't have any control on which thread will read the answer: did he mean to deliver or to order?
I've tried many possibilities, everyone not working:
- closing the ordering scanner from input, but it can't close;
- pausing the first thread from the other one, but you can't do that in Java;
- synchronizing everything, not working because the threads are meant to work together, not one at a time;
- use some semaphores/status boolean, but in that case I need to modify all the "ordering" part, including an infinite loop that checks that semaphores (I can't use acquire or release without stopping everything).
Any ideas/hints on how to solve the problem?
Have one thread and only one thread listening to UDP. It can store the results in a thread safe collection for the keyboard thread to read or wait on.
I was going through the javadocs and source code for drainTo method present in BlockingQueue interface and LinkedBlockingQueue implementation of the same. My understanding of this method after looking at the source (JDK7), is that the calling thread actually submits a Collection and afterwards acquires a takeLock(), which blocks other consumers. After that till the count of max elements, the items of the nodes are removed from the queue and put in a collection.
What I could appreciate is that it saves the threads from acquiring locks again and again, but pardon my limited knowledge, I could not appreciate the need for the same in real world examples. Could some one please share some real world examples where drainTo behavior is observable ?
Well, I used it in real life code and it looked quite natural to me: a background database thread creates items and puts them into a queue in a loop until either the end of data is reached or a stop signal is detected. On the first item a UI updater is launched using EventQueue.invokeLater. Due to the asynchronous nature and some overhead in this invokeLater mechanism, it will take some time until the UI updater comes to the point where it queries the queue and most likely more than one item may be available.
So it will use drainTo to get all items that are available at this specific point and update a ListDataModel which produces a single event for the added interval. The next update can be triggered using another invokeLater or using a Timer. So drainTo has the semantic of “gimme all items arrived since the last call” here.
On the other hand, polling the queue for single items could lead to a situation that producer and consumer are blocking each other for a short time and every time the consumer asks for a new item, another item is available due to the fact that the consumer has been blocked just long enough for the producer to create and put a new item. So you have to implement your own time limit to avoid blocking the UI thread too long in this case. Using drainTo once and release the event handling thread afterwards is much easier.
I am implementing a game and I want to ask the player to click on a specific view.
I want my control thread to wait until I get a value back (I have clicked on the view and handled the result). Currently I am doing this by creating a thread, running a method that asks them to click and then entering a while loop that is terminated when the mouse click event changes a variable used in the while loop.
I am writing a game where I have a thread constantly receiving events. On a specific event, I want to prompt the user for a response, but to do this would require me to be on the JavaFX thread (to my knowledge).
Is there a better way of doing this in JavaFX? Thanks!
There are several tools "hidden" in the JDK documentation on threads that can help you resolve this type of issue. Usually when we make a routine code wait for some condition that can proceed we use threads synchronizers.
I want my control thread to wait until I get a value back [...]
CountDownLatch, CyclicBarrier and FutureTask may be classes that can solve your problem. The functionality of these is quite simple. They have the function of stopping threads and release them when some condition is met. The difference in each of these classes is just semantics applied for termination and release threads. Read the documentation of each and see which one is most comfortable to you.
You can also take a look at other sources of study. There is no better source of study in the world (in my opinion) than the content within the book "Java Concurrency In Practice" by Brian Goetz. I assure you that you will become able to easily manipulate threads if you buy this book (or at least gain an incredible knowledge on the subject). Make it clear that you do not need to buy the book to solve your current problem. Buying the book is just my suggestion for you to have more knowledge about threads. You probably will solve your problem by looking at the documentation of classes that synchronize threads I mentioned.
Good luck in your projects. ;)
Similar to the question I posted yesterday, I have this problem that I just can't understand. The code is pretty simple and should (I think) generate a deadlock. I even reduced the number of accounts to 2, to increase the probability of deadlocks.
The code is really easy to understand but to put some context. I have a bank with accounts and I'm doing lots of transfers between accounts. The transfer method should generate a deadlock. Why isn't that happening?
I can only think that the code is running way too fast, but that seems improbable to happen all the time.
Here's the whole code:
http://pastebin.com/HWJpuT38
Problem is on this line:
mAccounts = new ArrayList<Account>(Collections.nCopies(slots, new Account()));
Basically, there is only one Account object, but lots of references to it. Thus you're only ever locking on a single object.
If you create lots of different Account objects, you should be able to see the deadlock quite quickly.
The only place where you have a 'contested' resource is where you synchronize on fromaccount and then on toaccount - everything else depends on one lock only.
If you had another method which synchronized on toaccount and then on fromaccount you might have a chance of causing deadlock, but as the code currently is it should be perfectly well-behaved.
I think you need to add some sort of sleep to your loop in AccountTransferRunnable otherwise the Scheduler will run the thread until end before starting the other one.
With a Sleep you will give the Scheduler the chance to switch to the other thread will the first one is still running, which will give your code the chance to run into a deadlock.
mAccounts = new ArrayList<Account>(Collections.nCopies(slots, new Account()));
http://download.oracle.com/javase/1.4.2/docs/api/java/util/Collections.html#nCopies%28int,%20java.lang.Object%29
You end up with a list of 2 references to the same object.
That object can only be locked by one thread at a time. You can never have a deadlock.
I assume you wanted to initialize mAccounts with 2 different instances of Account class.