今天去凤凰网面试了,可惜自己准备的东西都没有面到,有些紧张,其间有问到一个wait,notify的使用场景,答曰:生产者与消费者模式,当时只写了个大概,现在将代码贴出。
储存柜
package cuspro;
import java.util.ArrayList;
import java.util.List;
public class Storage {
private List<Object> foods;
public final static int MAX_SIZE = 5;
public Storage(){
foods = new ArrayList<Object>();
}
public List<Object> getFoods() {
return foods;
}
public void setFoods(List<Object> foods) {
this.foods = foods;
}
}
运行类,内部有:生产者,消费者两个内部类实现了Runnable接口:
package cuspro;
public class Company {
public static void main(String[] args) {
Company c = new Company();
Object lock = new Object();
Storage storage = new Storage();
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
new Thread(c.new Customer(storage, lock)).start();
new Thread(c.new Producer(storage, lock)).start();
new Thread(c.new Customer(storage, lock)).start();
new Thread(c.new Producer(storage, lock)).start();
new Thread(c.new Customer(storage, lock)).start();
new Thread(c.new Producer(storage, lock)).start();
new Thread(c.new Customer(storage, lock)).start();
new Thread(c.new Producer(storage, lock)).start();
new Thread(c.new Customer(storage, lock)).start();
new Thread(c.new Producer(storage, lock)).start();
new Thread(c.new Customer(storage, lock)).start();
new Thread(c.new Producer(storage, lock)).start();
}
/**
* 消费者
*
* @author xtuali
*
*/
private class Customer implements Runnable {
private Storage storage;
private Object lock;
public Customer(Storage storage, Object lock) {
super();
this.storage = storage;
this.lock = lock;
}
public void run() {
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
synchronized (lock) {
while (storage.getFoods().size() <= 0) {
try {
System.out.println("货物已空,提示生产者生产");
lock.wait(); //当前线程在lock上等待,并释放锁
} catch (InterruptedException e) {
e.printStackTrace();
}
}
storage.getFoods().remove(0);
lock.notifyAll(); //唤醒消费者与生产者
System.out.println("消费者消费1, "+Thread.currentThread().getName()+", 余量:"+storage.getFoods().size());
}
}
}
}
/**
* 生产者
*
* @author xtuali
*
*/
private class Producer implements Runnable {
private Storage storage;
private Object lock;
public Producer(Storage storage, Object lock) {
super();
this.storage = storage;
this.lock = lock;
}
public void run() {
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
synchronized (lock) {
while (storage.getFoods().size() >= Storage.MAX_SIZE) {
try {
System.out.println("货物已满,提示消费者消费");
lock.wait(); //当前线程在lock上等待,并释放锁
} catch (InterruptedException e) {
e.printStackTrace();
}
}
storage.getFoods().add(1);
lock.notifyAll(); //唤醒消费者与生产者
System.out.println("生产者生产1, "+Thread.currentThread().getName() +",余量:"+storage.getFoods().size());
}
}
}
}
}
之前考虑在Customer与Producer内部申明两个lock,一个是用来与Producer线程来通信,一个是用来与Customer线程来通信,但是锁没法释放,所以就只用了一个lock,但是这一个lock也解决了问题了!