消费者、生产者Java代码示例,wait

时间:2024-08-18 09:32:56

箱子中的苹果代表资源,现在有消费者从箱子中拿走苹果,生产者往箱子中放苹果。代码如下:

资源--箱子中的苹果:

public class Box {
int size;
int num; public Box(int size, int num) {
this.size = size;
this.num = num;
} public synchronized void put() {
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
while (num == 10) { //用while循环检查更好,在下面的wait()结束后还再判断一次,防止虚假唤醒
try {
System.out.println("箱子满了,生产者暂停。。。");
this.wait(); //等待消费者消费一个才能继续生产,所以要让出锁
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
}
}
num++;
System.out.println("箱子有空闲,开始生产。。。"+num);
this.notify(); //唤醒可能因为没苹果而等待的消费者
} public synchronized void take() {
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
while (num == 0) { //用while循环检查更好,在wait()结束后还再判断一次,防止虚假唤醒
try {
System.out.println("箱子空了,消费者暂停。。。");
this.wait(); //等待生产者生产一个才能继续消费,所以要让出锁
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
}
}
num--;
System.out.println("箱子有了,开始消费。。。"+num);
this.notify(); //唤醒可能因为苹果满了而等待的生产者
}
}

生产者、消费者:

public class Consumer implements Runnable {

    private Box box;

    public Consumer(Box box) {
this.box= box;
} @Override
public void run() {
while (true){
box.take();
} }
}
public class Producer implements Runnable {

    private Box box;

    public Producer(Box box) {
this.box= box;
} @Override
public void run() {
while (true){
box.put();
} }
}

Main方法:

public class ConsumerAndProducer {

    public static void main(String[] args) {
Box box = new Box(); Producer p1 = new Producer(box); //生产线程 Consumer c1 = new Consumer(box); //消费线程 new Thread(p1).start(); new Thread(c1).start();
}
}

以上,就是生产者消费者模式的Java代码实现。当然,我们完全可以使用JUC包的Lock接口下的类代替Synchronized完成代码同步:

Lock l = new ReentrantLock();
Condition condition = l.newCondition(); l.lock() //加锁 l.unlock() //释放锁 condition.await() //代替wait() condition.signal() //代替notify()

除了上述方法,也可以使用JUC包下BlockingQueue接口的阻塞队列完成,那样更简单。实际上,阻塞队列也是基于上述的基本思想实现的----队列满了就停止装入线程、空了就让取队列元素的线程等待。上述的Box就是一个阻塞队列的抽象模型(当然阻塞队列比这个还是要复杂很多)。