You should synchronize on the stack instead of pushing it at the method level, try this code.
Also, do not initialize the stack in your stream classes, since you pass them in the constructor from the main class, so this is not necessary.
Always try not to mark any method with a synchronized keyword, and not try to put a critical section of code in a synchronized block, because the larger the size of your synchronized area will affect performance more.
So, always put only this code in a synchronized block that needs thread safety.
Manufacturer Code
public void produce() { synchronized (A) { while (A.size() >= 5) { System.out.println("List is Full"); try { A.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } result = rand.nextInt(10); System.out.println(result + " produced "); A.push(result); System.out.println("stack ---"+A); A.notifyAll(); } }
User Code:
public void consume() { synchronized (A) { while (A.isEmpty()) { System.err.println("List is empty" + A + A.size()); try { System.err.println("wait"); A.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.err.println(A.pop() + " Consumed " + A); A.notifyAll(); } }
source share