===============
== ffff65535 ==
===============
十六个一[1111111111111111]

并发协作模型(生产者/消费者模式)-->管程法

default
方法名 作用
wait() Object wait() 方法让当前线程进入等待状态。直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法。
wait(long timeout) Object wait(long timeout) 方法让当前线程处于等待(阻塞)状态,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者超过参数 timeout 设置的超时时间。
如果 timeout 参数为 0,则不会超时,会一直进行等待,类似于 wait() 方法。
notify() Object notify() 方法用于唤醒一个在此对象监视器上等待的线程。
如果所有的线程都在此对象上等待,那么只会选择一个线程,选择是任意性的,并在对实现做出决定时发生。
notifyAll() Object notifyAll() 方法用于唤醒在该对象上等待的所有线程。优先级别高的线程有限调度。
notifyAll() 方法跟 notify() 方法一样,区别在于 notifyAll() 方法唤醒在此对象监视器上等待的所有线程,notify() 方法是一个线程。

https://www.runoob.com/java/java-object-wait.html

https://www.runoob.com/java/java-object-wait-timeout.html

https://www.runoob.com/java/java-object-notify.html

https://www.runoob.com/java/java-object-wait.html

参考资料:

https://www.bilibili.com/video/BV1V4411p7EF?p=25

  • 生产者:负责生产数据的模块(可能是方法,对象,线程,进程)
  • 消费者:负责处理数据的模块(可能是方法,对象,线程,进程)
  • 缓冲区:消费者不能直接使用生产者的数据,通过缓冲区进行传递
/**
 * @author
 */
public class TestPc {
    public static void main(String[] args) {
        Buffer buffer = new Buffer();
        new Producer(buffer).start();
        new Consumer(buffer).start();

    }
}

/**
 * 生产者
 */
class Producer extends Thread {
    private final Buffer buffer;

    public Producer(Buffer buffer) {
        this.buffer = buffer;
    }

    @Override
    public void run() {
        // 生产100个产品
        for (int i = 0; i < 100; i++) {
            buffer.push(new Product(i));
            System.out.println("生产了---->id为" + i + "的产品");
        }
    }
}

/**
 * 消费者
 */
class Consumer extends Thread {
    private final Buffer buffer;

    public Consumer(Buffer buffer) {
        this.buffer = buffer;
    }

    @Override
    public void run() {
        // 消费100个产品
        for (int i = 0; i < 100; i++) {
            Product pop = buffer.pop();
            System.out.println("消费了id为" + pop.getId() + "的产品");
        }
    }
}

/**
 * 缓冲区
 */
class Buffer {

    /**
     * 缓冲区大小
     */
    Product[] products = new Product[10];
    /**
     * 缓冲区计数器
     */
    int count = 0;

    /**
     * 生产者放入产品
     */
    public synchronized void push(Product product) {
        // 如果缓冲区满了,则等待消费者消费
        if (count >= 10) {
            // 通知消费者消费,生产者等待
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        // 如果没有满,则放入产品
        products[count] = product;
        count++;
        this.notifyAll();
    }

    /**
     * 消费者消费产品
     */
    public synchronized Product pop() {
        // 判断是否有产品可以消费
        if (count <= 0) {
            // 通知生产者生产,消费者消费
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        count--;
        // 如果存在产品,则消费
        Product product = products[count];
        this.notifyAll();
        return product;
        // 消费完了,通知生产
    }
}

/**
 * 产品
 */
class Product {
    /**
     * 产品变化
     */
    private final int id;

    public Product(int id) {
        this.id = id;
    }

    public int getId() {
        return id;
    }
}

这段代码有个问题,因为是使用数组当缓冲区的,并且是count++,count–进行处理的,所以类似于栈,所以早期生产的数据可能最后才会被消费。

而且count++,count–进行处理数据,不注意很容易下标越界,获取取个null出来