Multithreading -- producer and consumer issues

Problem: a classic case of multithreading is the problem of producers and consumers To operate the same resource together is to produce one product and consume another, which must take into account the safe synchronization of threads How to realize thread safety in multithreading and ensure the unity of resources

In the producer and consumer problem, both producers and consumers are multithreaded operations
Here is an object that executes the actions of producers and consumers. It is necessary to judge the products, and judge when to produce and when to consume

/**Operation data*/
class Product{
    int num;//Number of products

    //Let the producer produce and start production when the quantity is less than 20
    public synchronized void addProduct(){
        if (num>=20){//If it is greater than 20, there is no need to produce
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }else {
            num++;
            System.out.println("The producer begins to produce the second product"+ num +"Piece product");
            notifyAll();//If the number of products is greater than 0, the consumption thread that stops when the number is less than 0 can be awakened
        }
    }
    //Let consumers consume, as long as the quantity is greater than 0, they can start to consume
    //Consumption action
    public synchronized void reduceProduct(){
        if (num>0){
            System.out.println("Consumers start spending"+ num +"Piece product");
            num--;
            notifyAll();//If the quantity is greater than 0, consumption can start. When the product data is 20, reduce the products, and then the producers can also start production. Therefore, wake up the producers
        }else {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }
}
Producer's execution code:
/**producer*/
class Producer implements Runnable{
    Product product;//Introduce the object to operate on
    public Producer(Product product) {
        this.product = product;
    }

    @Override
    public void run() {
            while (true){
                this.product.addProduct();
            }
    }
}

Consumer's execution code:

/**consumer*/
class Consumer implements Runnable{
    Product product;
    public Consumer(Product product) {
        this.product = product;
    }

    @Override
    public void run() {
        while (true){
            this.product.reduceProduct();
        }
    }


}

The above is based on the idea of Shang * * of an organization. The following is the crazy God's management method in station B (solved through buffer zone)

Shared products

/**product*/
class Clicken{
    int id;//number
    public Clicken(int id) {
        this.id = id;
    }
}

Producer's execution code

/**producer*/
class Productor extends Thread{

    SynContainer synContainer;
    public Productor(SynContainer synContainer){
        this.synContainer =synContainer;
    }

    @Override
    public void run() {//Production action
        for (int i = 1; i < 100; i++) {
            synContainer.push(new Clicken(i));
            System.out.println("Produced" + i +"Chicken");
        }
    }
}

Consumer's execution code

/**consumer*/
class Customer extends Thread{

    SynContainer synContainer;
    public Customer(SynContainer synContainer){
        this.synContainer =synContainer;
    }

    @Override
    public void run() { //Consumption action
        for (int i = 0; i < 100; i++) {
            System.out.println("Consumption" +  synContainer.pop().id +"Chicken");
        }
    }
}

buffer

/**buffer*/
class SynContainer{

    Clicken[] clickens = new Clicken[10]; //The need for a container size means that within this range, producers and consumers decide whether to carry out production or consumption

    int count = 0;// //Container counter number of chickens

    /**Producers put in products*/
    public synchronized void push(Clicken clicken){
        if (count == clickens.length){ //If the container is full, wait for the consumer to consume. / / inform the consumer to consume and wait for production
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        clickens[count] = clicken;//If the container is not full, it needs to be produced by the producer
        count++;
        //Inform consumers that they can consume
        this.notify();
    }

    /**Consumer products*/
    public synchronized Clicken pop(){
        if (count==0){ //Judge whether it can be consumed or not -- > it needs to be produced by the producer
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        count--;//Can consume -- > consumer consumption
        Clicken clicken = clickens[count];

        //Inform the producer of production
        this.notify();
        return clicken;
    }
}

The execution entry of both is

    public static void main(String[] args) {
        Product product = new Product();
        Producer producer = new Producer(product);
        Consumer consumer = new Consumer(product);
        new Thread(producer).start();
        new Thread(consumer).start();

    }

The above two ideas are roughly the same. When writing these codes, I was a little confused about why I had to judge whether to carry out production and consumption actions in an independent object. I was still a little confused when watching the videos of Shang Silicon Valley, and then compared the crazy idea. In fact, this is an idea of object-oriented programming, The data shared by the two are independent, and then the producer is only responsible for generation and the consumer is only responsible for consumption. They perform their respective duties. The operations that need to be judged are placed in another object to reduce the coupling of the code In fact, my personal understanding of object-oriented programming is not enough. The road is long and blocked

Keywords: Java

Added by dankus on Tue, 08 Mar 2022 10:56:22 +0200