Producer Consumer (Semaphore?)

I am trying to understand concurrency in Java and have tried to code a producer consumer example:

package de.fasel;

publicclass PackagingUnit{

privateint numberOfUnits;

privatestaticfinalint PACKAGE_SIZE = 50;

public PackagingUnit(){

this.numberOfUnits = 0;

}

publicvoid addUnit(){

numberOfUnits++;

notify();

}

publicvoid getPackage(){

while (this.numberOfUnits < 50)

try{

wait();

}catch (InterruptedException e){

// TODO Auto-generated catch block

e.printStackTrace();

}

this.numberOfUnits -= PACKAGE_SIZE;

}

}

package de.fasel;

import java.util.concurrent.TimeUnit;

publicclass Producerimplements Runnable{

privateint productionTime;

private PackagingUnit pUnit;

private String name;

/**

* @param productionTime in sec int

* @param pUnit

* @param name

*/

public Producer(int productionTime, PackagingUnit pUnit, String name){

this.productionTime = productionTime;

this.pUnit = pUnit;

this.name = name;

}

publicvoid run(){

while (true){

try{

TimeUnit.SECONDS.sleep(productionTime);

}catch (InterruptedException e){

// TODO Auto-generated catch block

e.printStackTrace();

}

this.pUnit.addUnit();

System.out.printf("%s has produced one unit", name);

}

}

}

package de.fasel;

publicclass Shipperimplements Runnable{

private PackagingUnit pUnit;

public Shipper(PackagingUnit unit){

super();

// TODO Auto-generated constructor stub

pUnit = unit;

}

publicvoid run(){

while(true){

this.pUnit.getPackage();

System.out.println("One package has been shipped");

}

}

}

package de.fasel;

publicclass Tester{

publicstaticvoid main(String[] args){

PackagingUnit pUnit =new PackagingUnit();

Producer p1 =new Producer(3, pUnit,"p1");

Producer p2 =new Producer(2, pUnit,"p2");

Producer p3 =new Producer(1, pUnit,"p3");

Producer p4 =new Producer(1, pUnit,"p4");

Shipper s =new Shipper(pUnit);

Thread tp1 =new Thread(p1);

tp1.start();

Thread tp2 =new Thread(p2);

tp2.start();

Thread tp3 =new Thread(p3);

tp3.start();

Thread tp4 =new Thread(p4);

tp4.start();

Thread ts =new Thread(s);

ts.start();

}

}

When I run this I get the following exception

Exception in thread "Thread-4" java.lang.IllegalMonitorStateException: current thread not owner

at java.lang.Object.wait(Native Method)

at java.lang.Object.wait(Unknown Source)

at de.fasel.PackagingUnit.getPackage(PackagingUnit.java:20)

at de.fasel.Shipper.run(Shipper.java:15)

at java.lang.Thread.run(Unknown Source)

How can I make this work?

Thanks

[6275 byte] By [MarcusDidiusa] at [2007-10-2 22:15:18]
# 1
What have you tried? Have you read the documentation for IllegalMonitorStateException?
dannyyatesa at 2007-7-14 1:32:18 > top of Java-index,Core,Core APIs...
# 2

>>Thrown to indicate that a thread has attempted to wait on an object's monitor or to notify other threads waiting on an object's monitor without owning the specified monitor.

Sorry that's a bit abstract, I am just trying to learn this stuff. I thought that was supposed to happen: One or several threads waiting for a resource until it becomes available. Why is this exception thrown?

The PackagingUnit is designed analogous to the semaphore pattern from an IBM tutorial (Axel Roetter: Writing multithreaded Java applications). Unfortunately it does not show how to use (perhaps it is to obvious to most people).

MarcusDidiusa at 2007-7-14 1:32:18 > top of Java-index,Core,Core APIs...
# 3
Ok. I have figured it out.The methods addUnit and getPackage must be marked assynchronized.
MarcusDidiusa at 2007-7-14 1:32:18 > top of Java-index,Core,Core APIs...