Java wait notify consumer producer example 2017-11-23 07:03
wait
, notify
and notifyAll
are all method of Object
. It means that every object in java can be a lock monitor. When you use synchronized
you get the lock of object. Use synchronized
on the method current thread will get the lock of instance. If you add synchronized
on a static method that means current thread will get the lock of this Class
. These 3 methods can not be used without synchronized
(you can release the lock without geting it).
As we all known, BlockingQueue
can help you to implement "producer-consumer" model (you can click Java blockingqueue producer consumer example for more detail). In this page I will show you how to use wait
and notify
to implement "producer-consumer" model.
code
public class Product {
private String name;
public Product(String name) {
this.name = name;
}
//getter and setter method
}
public class Warehouse {
private final int MAX_NUM = 10;
private final List<Product> products = new LinkedList<>();
private Random random = new Random();
public void add(Product product) throws InterruptedException {
synchronized (products) {
do {
if (products.size() >= MAX_NUM) {
products.wait();
} else {
break;
}
} while (true);
products.add(product);
System.out.println("current size:" + products.size());
products.notify();
}
}
public Product remove() throws InterruptedException {
synchronized (products) {
do {
if (products.size() == 0) {
products.wait();
} else {
break;
}
} while (true);
int tobeSoldIndex = random.nextInt(products.size());
Product removedProduct = products.remove(tobeSoldIndex);
products.notify();
System.out.println("current size:" + products.size());
return removedProduct;
}
}
}
public class Producer implements Runnable {
private Warehouse warehouse;
private String producerName;
public Producer(String producerName, Warehouse warehouse) {
this.producerName = producerName;
this.warehouse = warehouse;
}
@Override
public void run() {
do {
try {
for (int i = 0; i < 10; i++) {
Product product = new Product(producerName + "-No. :" + i);
System.out.println("add product");
warehouse.add(product);
Thread.sleep(2000);
}
} catch (Exception e) {
e.printStackTrace();
}
} while (true);
}
}
public class Consumer implements Runnable {
private String consumerName;
private Warehouse warehouse;
public Consumer(String consumerName, Warehouse warehouse) {
this.consumerName = consumerName;
this.warehouse = warehouse;
}
@Override
public void run() {
try {
do {
Product removedProduct = warehouse.remove();
System.out.println(consumerName + " remove product:" + removedProduct.getName());
Thread.sleep(3000);
} while (true);
} catch (Exception e) {
e.printStackTrace();
}
}
}
analyze
wait
method will release the currently acquired lock, and block current thread.notify
method will wake up one thread (randomly select one) which blocked by the lock, and if all goes well this thread will get the lock.notifyAll
method will wake up all thread which blocked by the lock, and highest priority one will get the lock, and if all goes well this thread will get the lock.
EOF