Why my producer consumer program is blocking? - java

I have created my own queue .
Queue.java
public class MyQueue {
private int size;
private Queue<String> q;
public MyQueue(int size ,Queue<String> queue) {
this.size = size;
this.q = queue;
}
//getter and setter
public synchronized void putTail(String s) {
System.out.println(this.size); // It should print 0, 1,2
while (q.size() != size) {
try {
wait();
}
catch (InterruptedException e) {
}
}
Date d = new Date();
q.add(d.toString());
notifyAll();
}
}
MyProducer.java
import com.conpro.MyQueue;
public class MyProducer implements Runnable {
private final MyQueue queue;
private final int size;
MyProducer(int size,MyQueue q) { this.queue = q; this.size = size; }
#Override
public void run()
{
queue.putTail(String.valueOf(Math.random()));
}
}
MyTest.java
public class MyTest {
public static void main(String[] args) {
Queue q = new PriorityQueue<String>();
MyQueue mq = new MyQueue(3,q);
MyProducer p = new MyProducer(3,mq);
MyProducer p1 = new MyProducer(3,mq);
MyProducer p2 = new MyProducer(3,mq);
new Thread(p).start();
new Thread(p1).start();
new Thread(p2).start();
}
}
Now Here I have created 3 producer .
So after executing this 3 lines , queue should be full.
Output should be :
0
1
2
But it is only printing 0.
Why?
P.S : I have written only producer code since I have not reached there yet.

Since putTail() is synchronized, only one of the three threads can enter it. That thread then sits forever inside the while (q.size() != size) loop, while the other two threads remain unable to enter the method.

The problem is that all 3 threads enter the wait() but never get notified via notifyAll
There's problem with your code that doesn't really make it a blocking queue. Here's what I would expect a blocking queue to do:
Queue is bound to maximum size of 3, start with no elements
Get something from a producer, size is not yet 3, add it, don't block
Get something else from a producer, size is not yet 3, add it, don't block
Get something else from a producer, size is not yet 3, add it, don't block
Get something else from a producer, size is now 3, block until something is taken
Get something else from a producer, size is still 3, block until something is taken
A consumer takes from the queue, the threads from (5) and (6) are notified, and the first one to get scheduled obtains the lock long enough to add his element, the other one is forced to block again until another consumer takes from the queue.
Here's what yours is actually doing as-written:
Queue is bound to maximum size of 3, start with no elements
Get something from a producer, size is not yet 3, block on wait() without adding it
Get something from a producer, size is not yet 3, block on wait() without adding it
Get something from a producer, size is not yet 3, block on wait() without adding it
In all 3 cases of adding the element, the element doesn't actually get added, and we get stuck at wait() because all 3 enter the while loop, then nothing ever calls notifyAll().
Your fix in the comments:
while (q.size() == size)
This makes it do what it's supposed to: if the size has already reached the maximum, block until it's told to continue via a notify, then check if the size is still the maximum. For the thread from my example above that receives the lock after being notified (e.g. the thread from step 6), it will get the chance to add its message. The thread that doesn't receive the lock will receive the lock after the first one releases it, but the size will have increased to the max size again, which causes it to block again. That being said, I think your approach is a good start.
The one thing in your code that's incorrect is that you're calling notifyAll after you add it. Adding will never cause the queue size to shrink, but you're notifying all the threads waiting in the putTail method to continue. There's no reason to notify the threads that are waiting to add something to the queue if you just put something into it that made it reach the maximum size anyway. I think you meant for that notify to do something with the threads waiting on your eventual take method, which leads me to my next point:
Your next step will be to have two lock objects instead of always using this. That way the take method can block separately from the put method. Use one lock to wait in the put method and notifyAll on it in take, then use the other lock to wait in the take method and notifyAll on it in put. This will make it so that you can separately notify the takers and putters without notifying all of them at once like you would using this.notifyAll.

The problem is in MyQueue class's putTail() method.There you are calling wait() on this (current object),and it never be notified.Then the thread will wait forever.

Related

Producer and Consumer in java use notify() and wait() run 4 threads

Recently ,I learned about the notify and wait in Java Thread Communication, and I tried to write the classical problem of Consumer&Producer, in my code ,I actually have 4 threads ,2 are consumers and the other 2 are producers.
package producer_consumer;
class Shared {
private volatile boolean writable = true;
public Character character = 'A';
public synchronized void produceChar(Character c) {
while (!writable) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
writable = false;
character = c;
notify();
}
public synchronized void consumerChar() {
while (writable) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
writable = true;
notify();
}
}
public class PC {
public static void main(String[] args) {
Shared shared = new Shared();
class Producer extends Thread {
#Override
public synchronized void run() {
for(Character character = 'A';character<'Z';character++) {
shared.produceChar(character);
System.out.println(shared.character + " is produced");
}
}
}
class Consumer extends Thread {
#Override
public synchronized void run() {
do {
shared.consumerChar();
System.out.println(shared.character + " is consumed");
}while (shared.character!='Z');
}
}
Producer p1 = new Producer();
Producer p2 = new Producer();
Consumer c1 = new Consumer();
Consumer c2 = new Consumer();
p1.start();
p2.start();
c1.start();
c2.start();
}
}
however,when I tried to run the code , it didn't work out. I supposed it will print the letters from A to Z ,but it always get stucked. I know there must be something wrong ,but I can't figure it out by myself. Actually ,I don't konw what's wrong with it . So ,anyone will help me ? Thank you!
When your code calls notify, that tells the scheduler to pick one thread from the waitset for the lock you called notify on, and wake it up. The scheduler has no knowledge of what specific condition the threads are waiting for and there's no telling which one it will pick.
When you have multiple threads, some of which are waiting on different conditions (here the conditions are writable and not writable), then it's possible for a thread to be notified for a condition that it is not interested in. The notified thread goes back to waiting once it figures out the condition it's looking for isn't present, and no other thread receives it. That means nobody makes progress as a result of that event.
Example:
1) First producer executes, writable is true, letting it skip waiting, write s char, call notify (nobody's listening), and flip the writable flag to false.
2) Context switch to second producer, it finds writable is false so it waits.
3) At this point the scheduler could run a consumer if one is through starting, or it could switch back to the first producer.
Say it picks the producer. The first producer sees writable is still false, so it waits.
4) the first consumer runs. Writable is false so no waiting; it flips the writable flag to true and calls notify.
5) now 2 producers are waiting, the notify will wake one of them, the other is still waiting.
6) the first consumer can be picked to run again, writable is true so it waits. Now there is one producer waiting and one consumer waiting.
7) At this point the scheduler can pick either the remaining active consumer or the remaining active producer. If it picks the producer then the producer can act, then call notify. Either waiting thread could be notified. Only one can act on the notification.
One solution is to use notifyAll. That wakes up all the threads in the waitset, so if any of them are interested then they'll be notified. This is not a perfect solution for all cases; in a program with a lot of threads it can mean a lot of unproductive context switching and state transitions for most of the threads, who end up eventually going back to their wait state without having made any headway. For a small program that's not an issue, of course.
A real world solution without the downside of notifyAll is to use ReentrantLock, which allows separate conditions. That way threads wait on specific Condition objects, with the result that the notification goes only to a thread that is waiting for that specific condition.
The api doc for Condition has an example of a bounded fixed size queue that shows threads waiting on different condition objects depending on if they are producers or consumers. The conditions are not empty and not full. Threads inserting things to a full queue have to wait for the not full condition. Threads trying to take items out of an empty queue wait for the not empty condition.
Btw putting synchronized on the run method doesn't accomplish anything. Each thread is acquiring a lock on itself for the life of the thread. Locks must be shared in order to be useful. All it does is make it difficult for a thread joining on any of these to enter the waiting state.

Producer/Consumer: no producer/consumer should block other producer/consumer

I am designing a system where there will be n producers and m consumers, where n and m are numbers, and n != m.
I wanted to design the system such a way that,
no producer should block other producer when producing
no consumer should block other consumer when consuming neither
producer nor consumer block each other while producing/consuming
For eg: in java if i use the synchronized key word, then it will be blocking the respective caller.
I am not sure what data structure and algorithm i should use to implement this system.
Can some one provide me help/pointers on this?
You probably want something like the ConcurrentLinkedQueue. The idea is that you create a single queue. Each of your n producers adds work items to the queue, and each of the m consumers reads work items from the queue. The producer is simply:
while not done
create work item
add work item to queue
The consumer is just as simple:
while not done
get next work item from queue
process work item
The ConcurrentLinkedQueue methods handle adding and removing items, synchronizing with the other producers and consumers as required.
The only real drawback is that you have to poll the queue to see if there are items. So you'll probably want an auto reset event that gets tripped whenever an item is added to the queue. For example:
add work item to queue
set ItemAvailable event
And the consumer would poll the queue and if no item is available, wait on the event:
while not done
while ((item = queue.poll) == null)
wait on ItemAvailable event
process item
Take a look at the example I linked. It really isn't difficult to use.
Depending on how much heavy lifting you need to do, and how well your solution need to scale, RxJava has a bit of a steep learning curve, but once you got past that it's probably the most elegant, scaling and performing solution.
Run all your producers in different threads, combine them with Merg(), move the consumers to there own thread on a unbound buffer with .observeOn(Scheduler.newThread()).
If you need something that runs well parallel on multiple systems, look at mapreduce.
If you need something at the complete other end of the spectrum (something simple), simply stick to a ConcurrentQueue. That doesn't support multicast, but at least solves the producer side of the problem.
You want an approach where every action would be atomic and uninterruptible, so yes, in my opinion the best approach would be to use synchronized modifier on methods to set the lock.
The other interesting approach would be to use atomic variables -> http://baptiste-wicht.com/posts/2010/09/java-concurrency-atomic-variables.html
That depends on your data in these producer/consumer structures.
use wait() and notify() for thread communication , u can create n producer and m consumer threads
class Q{
int n;
boolean value=false;
synchronized int get() {
if(!value)
try { wait(); }
catch(InterruptedException e)
{ System.out.println("thread interrupted"); }
System.out.println("Got : "+n);
value=false;
notify();
return n;}
synchronized void put(int n) {
if(value)
try { wait();}
catch(InterruptedException e)
{ System.out.println("thread interrupted"); }
this.n=n;
value=true;
System.out.println("Put : "+n);
notify();}}
class Producer implements Runnable{
Q q;
Producer(Q q){
this.q=q;
new Thread(this,"Producer").start();}
public void run(){
int i=0;
while(true)
{
q.put(i++);}}
}
class Consumer implements Runnable{
Q q;
Consumer(Q q) {
this.q=q;
new Thread(this,"Consumer").start();}
public void run(){
while(true)
{
q.get();
}}}
class PCFixed
{
public static void main(String ar[])
{
Q q=new Q();
new Producer(q);
new Consumer(q);
System.out.println("PRESS CONTROL-C TO STOP");
}
}
it goes to infinity, change that based on ur requirements

Thread synchronization- When does a thread release the lock on an object

public class MyStack2 {
private int[] values = new int[10];
private int index = 0;
public synchronized void push(int x) {
if (index <= 9) {
values[index] = x;
Thread.yield();
index++;
}
}
public synchronized int pop() {
if (index > 0) {
index--;
return values[index];
} else {
return -1;
}
}
public synchronized String toString() {
String reply = "";
for (int i = 0; i < values.length; i++) {
reply += values[i] + " ";
}
return reply;
}
}
public class Pusher extends Thread {
private MyStack2 stack;
public Pusher(MyStack2 stack) {
this.stack = stack;
}
public void run() {
for (int i = 1; i <= 5; i++) {
stack.push(i);
}
}
}
public class Test {
public static void main(String args[]) {
MyStack2 stack = new MyStack2();
Pusher one = new Pusher(stack);
Pusher two = new Pusher(stack);
one.start();
two.start();
try {
one.join();
two.join();
} catch (InterruptedException e) {
}
System.out.println(stack.toString());
}
}
Since the methods of MyStack2 class are synchronised, I was expecting the output as
1 2 3 4 5 1 2 3 4 5. But the output is indeterminate. Often it gives : 1 1 2 2 3 3 4 4 5 5
As per my understanding, when thread one is started it acquires a lock on the push method. Inside push() thread one yields for sometime. But does it release the lock when yield() is called? Now when thread two is started, would thread two acquire a lock before thread one completes execution? Can someone explain when does thread one release the lock on stack object?
A synchronized method will only stop other threads from executing it while it is being executed. As soon as it returns other threads can (and often will immediately) get access.
The scenario to get your 1 1 2 2 ... could be:
Thread 1 calls push(1) and is allowed in.
Thread 2 calls push(1) and is blocked while Thread 1 is using it.
Thread 1 exits push(1).
Thread 2 gains access to push and pushes 1 but at the same time Thread 1 calls push(2).
Result 1 1 2 - you can clearly see how it continues.
When you say:
As per my understanding, when thread one is started it acquires a lock on the push method.
that is not quite right, in that the lock isn't just on the push method. The lock that the push method uses is on the instance of MyStack2 that push is called on. The methods pop and toString use the same lock as push. When a thread calls any of these methods on an object, it has to wait until it can acquire the lock. A thread in the middle of calling push will block another thread from calling pop. The threads are calling different methods to access the same data structure, using the same lock for all the methods that access the structure prevents the threads from accessing the data structure concurrently.
Once a thread gives up the lock on exiting a synchronized method the scheduler decides which thread gets the lock next. Your threads are acquiring locks and letting them go multiple times, every time a lock is released there is a decision for the scheduler to make. You can't make any assumptions about which will get picked, it can be any of them. Output from multiple threads is typically jumbled up.
It seems like you may have some confusion on exactly what the synchronized and yield keywords mean.
Synchronized means that only one thread can enter that code block at a time. Imagine it as a gate and you need a key to get through. Each thread as it enters takes the only key, and returns it when they are done. This allows the next thread to get the key and execute the code inside. It doesn't matter how long they are in the synchronized method, only one thread can enter at a time.
Yield suggests (and yes its only a suggestion) to the compiler that the current thread can give up its allotted time and another thread can begin execution. It doesn't always happen that way, however.
In your code, even though the current thread suggest to the compiler that it can give up its execution time, it still holds the key to the synchronized methods, and therefore the new thread cannot enter.
The unpredictable behavior comes from the yield not giving up the execution time as you predicted.
Hope that helped!

Sliding window with 50% overlap with producer/consumer threads

I have the following scenario in Java:
1 producer thread stores event objects into a queue. Blocking it is not an option. It should always just store each element at the end of the queue and exit (so no bounded queues).
1 consumer thread waits for the queue to have WINDOW_SIZE number of events in it. It should then retrieve all WINDOW_SIZE events from the queue for processing, but only remove half of them (i.e. WINDOW_SIZE/2), for a 50% overlap.
My question is, which (concurrent) collection would you use to implement this efficiently? The events come in at 100Hz on a resource-limited device (a mobile phone running Android). I thought of using the following, none of which seem to be a proper fit:
A ConcurrentLinkedQueue, checking for queue size each time it is modified, and using peek()/poll() in the consumer when WINDOW_SIZE events are available. This seems a bit cumbersome.
An ArrayBlockingQueue, again checking for queue size, and using drainTo(). However, that method has the following documentation: "[...] Further, the behavior of this operation is undefined if the specified collection is modified while the operation is in progress. [...]". This seems a bit odd for a concurrent collection.
Here's some example code:
import java.util.Queue;
import com.google.common.collect.Queues;
public class AccelerometerProcessor implements Runnable {
private static final int WINDOW_SIZE = 128;
private final Queue<AccelerometerEvent> eventQueue = Queues.newConcurrentLinkedQueue();
#Override
public void run() {
while (!Thread.interrupted()) {
try {
synchronized (eventQueue) {
while (eventQueue.size() < WINDOW_SIZE) {
eventQueue.wait();
}
// We have WINDOW_SIZE eventQueue, start processing
}
} catch (InterruptedException e) {
// Do nothing
}
}
}
public void addAccelerometerEvent(AccelerometerEvent accelerometerEvent) {
synchronized (eventQueue) {
eventQueue.add(accelerometerEvent);
eventQueue.notifyAll();
}
}
}
I'm using Google Guava also, by the way, so if there's a nice collection in there I haven't heard about, please refer me.
So: Any good ideas how to solve this efficiently and cleanly?
If you're always going to consume WINDOW_SIZE/2 events en bloc, why doesn't the producer thread (you said there's only one) fill an array of size WINDOW_SIZE/2 and pass it to the queue once it's full?

How to correctly use synchronized?

This piece of code:
synchronized (mList) {
if (mList.size() != 0) {
int s = mList.size() - 1;
for (int i = s; i > 0; i -= OFFSET) {
mList.get(i).doDraw(canv);
}
getHead().drawHead(canv);
}
}
Randomly throws AIOOBEs. From what I've read, the synchronized should prevent that, so what am I doing wrong?
Edits:
AIOOBE = Array Index Out Of Bounds Exception
The code's incomplete, cut down to what is needed. But to make you happy, OFFSET is 4, and just imagine that there is a for-loop adding a bit of data at the beginning. And a second thread reading and / or modifying the list.
Edit 2:
I've noticed it happens when the list is being drawn and the current game ends. The draw-thread hasn't drawn all elements when the list is emptied. Is there a way of telling the game to wait with emtying the list untill it's empty?
Edit 3:
I've just noticed that I'm not sure if this is a multi-threading problem. Seems I only have 2 threads, one for calculating and drawing and one for user input.. Gonna have to look into this a bit more than I thought.
What you're doing looks right... but that's all:
It doesn't matter on what object you synchronize, it needn't be the list itself.
What does matter is if all threads always synchronize on the same object, when accessing a shared resource.
Any access to SWING (or another graphic library) must happen in the AWT-Thread.
To your edit:
I've noticed it happens when the list is being drawn and the current game ends. The draw-thread hasn't drawn all elements when the list is emptied. Is there a way of telling the game to wait with emtying the list untill it's empty?
I think you mean "...wait with emptying the list until the drawing has completed." Just synchronize the code doing it on the same lock (i.e., the list itself in your case).
Again: Any access to a shared resource must be protected somehow. It seems like you're using synchronized just here and not where you're emptying the list.
The safe solution is to only allow one thread to create objects, add and remove them from a List after the game has started.
I had problems myself with random AIOOBEs erros and no synchornize could solve it properly plus it was slowing down the response of the user.
My solution, which is now stable and fast (never had an AIOOBEs since) is to make UI thread inform the game thread to create or manipulate an object by setting a flag and coordinates of the touch into the persistent variables.
Since the game thread loops about 60 times per second this proved to be sufficent to pick up the message from the UI thread and do something.
This is a very simple solution and it works great!
My suggestion is to use a BlockingQueue and I think you are looking for this solution also. How you can do it? It is already shown with an example in the javadoc :)
class Producer implements Runnable {
private final BlockingQueue queue;
Producer(BlockingQueue q) { queue = q; }
public void run() {
try {
while (true) { queue.put(produce()); }
} catch (InterruptedException ex) { ... handle ...}
}
Object produce() { ... }
}
class Consumer implements Runnable {
private final BlockingQueue queue;
Consumer(BlockingQueue q) { queue = q; }
public void run() {
try {
while (true) { consume(queue.take()); }
} catch (InterruptedException ex) { ... handle ...}
}
void consume(Object x) { ... }
}
class Setup {
void main() {
BlockingQueue q = new SomeQueueImplementation();
Producer p = new Producer(q);
Consumer c1 = new Consumer(q);
Consumer c2 = new Consumer(q);
new Thread(p).start();
new Thread(c1).start();
new Thread(c2).start();
}
}
The beneficial things for you are, you need not to worry about synchronizing your mList. BlockingQueue offers 10 special method. You can check it in the doc. Few from javadoc:
BlockingQueue methods come in four forms, with different ways of handling operations that cannot be satisfied immediately, but may be satisfied at some point in the future: one throws an exception, the second returns a special value (either null or false, depending on the operation), the third blocks the current thread indefinitely until the operation can succeed, and the fourth blocks for only a given maximum time limit before giving up.
To be in safe side: I am not experienced with android. So not certain whether all java packages are allowed in android. But at least it should be :-S, I wish.
You are getting Index out of Bounds Exception because there are 2 threads that operate on the list and are doing it wrongly.
You should have been synchronizing at another level, in such a way that no other thread can iterate through the list while other thread is modifying it! Only on thread at a time should 'work on' the list.
I guess you have the following situation:
//piece of code that adds some item in the list
synchronized(mList){
mList.add(1, drawableElem);
...
}
and
//code that iterates you list(your code simplified)
synchronized (mList) {
if (mList.size() != 0) {
int s = mList.size() - 1;
for (int i = s; i > 0; i -= OFFSET) {
mList.get(i).doDraw(canv);
}
getHead().drawHead(canv);
}
}
Individually the pieces of code look fine. They seam thread-safe. But 2 individual thread-safe pieces of code might not be thread safe at a higher level!
It's just you would have done the following:
Vector v = new Vector();
if(v.length() == 0){ v.length() itself is thread safe!
v.add("elem"); v.add() itself is also thread safe individually!
}
BUT the compound operation is NOT!
Regards,
Tiberiu

Categories

Resources