生产消费者模型,大家都比较熟悉。面试bat等大厂就遇到了两次让手动实现,这里写上我的理解与实现。
实现步骤:

  1. 定义共有内容。
    1. List,容器本身,也是锁的对象。
    2. MAX_NUM,代表容器最大容量,标识容器是否已满
  2. 编写线程,编写producer与consumer的方法(本文讲方法单独取出。)
  3. 启动线程。
package com.真题;

import java.util.ArrayList;
import java.util.LinkedList;

public class 生产者消费者 {
    public static int MAX_NUM = 10;
    public static LinkedList<Integer> list = new LinkedList<>();

    public void producer() {
        synchronized (list) {
            //full
            while (list.size() + 1 > MAX_NUM) {
                System.out.println("list 满了,生产者" + Thread.currentThread().getName() + "等待.");
                try {
                    list.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            //not full
            int v = (int) (Math.random() * 100);
            list.add(v);
            System.out.println("【生产者" + Thread.currentThread().getName()
                    + "】生产一个产品:" + v + ",现库存为 " + list.size() + "个,list:" + list);
            list.notifyAll();
        }
    }

    public void consumer() {
        synchronized (list) {
            //empty
            while (list.size() == 0) {
                System.out.println("list 为空,消费者" + Thread.currentThread().getName() + "等待.");
                try {
                    list.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            int x = list.removeFirst();
            System.out.println("【消费者" + Thread.currentThread().getName()
                    + "】消费一个产品:" + x + ",现库存为 " + list.size() + "个,list:" + list);

            list.notifyAll();
        }
    }

    static class Pro extends Thread {
        生产者消费者 s = new 生产者消费者();

        @Override
        public void run() {
            super.run();
            while (true) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                s.producer();
            }
        }
    }

    static class Con extends Thread {
        生产者消费者 s = new 生产者消费者();
        @Override
        public void run() {
            super.run();
            while (true) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                s.consumer();
            }

        }
    }

    public static void main(String[] args) {
        Pro pro = new Pro();
        Pro pro1 = new Pro();
        Pro pro2 = new Pro();
        Con con = new Con();
        Con con1 = new Con();
        Con con2 = new Con();


        pro.start();
        pro1.start();
        pro2.start();
        con.start();
        con1.start();
//        con2.start();
    }
}

/*
结果:

【生产者Thread-0】生产一个产品:54,现库存为 1个,list:[54]
【消费者Thread-4】消费一个产品:54,现库存为 0个,list:[]
【生产者Thread-2】生产一个产品:67,现库存为 1个,list:[67]
【生产者Thread-1】生产一个产品:24,现库存为 2个,list:[67, 24]
【消费者Thread-3】消费一个产品:67,现库存为 1个,list:[24]
【消费者Thread-3】消费一个产品:24,现库存为 0个,list:[]
【生产者Thread-1】生产一个产品:10,现库存为 1个,list:[10]
【消费者Thread-4】消费一个产品:10,现库存为 0个,list:[]
【生产者Thread-2】生产一个产品:66,现库存为 1个,list:[66]
【生产者Thread-0】生产一个产品:9,现库存为 2个,list:[66, 9]
【生产者Thread-0】生产一个产品:50,现库存为 3个,list:[66, 9, 50]
【消费者Thread-4】消费一个产品:66,现库存为 2个,list:[9, 50]
【消费者Thread-3】消费一个产品:9,现库存为 1个,list:[50]
【生产者Thread-1】生产一个产品:9,现库存为 2个,list:[50, 9]
【生产者Thread-2】生产一个产品:54,现库存为 3个,list:[50, 9, 54]
【生产者Thread-2】生产一个产品:4,现库存为 4个,list:[50, 9, 54, 4]
【消费者Thread-3】消费一个产品:50,现库存为 3个,list:[9, 54, 4]
【生产者Thread-0】生产一个产品:88,现库存为 4个,list:[9, 54, 4, 88]
【生产者Thread-1】生产一个产品:70,现库存为 5个,list:[9, 54, 4, 88, 70]
【消费者Thread-4】消费一个产品:9,现库存为 4个,list:[54, 4, 88, 70]
【消费者Thread-4】消费一个产品:54,现库存为 3个,list:[4, 88, 70]
【生产者Thread-2】生产一个产品:81,现库存为 4个,list:[4, 88, 70, 81]
。。。
	没有尽头
*/

欢迎指正!

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐