Multithreading: producer consumer (tube method, semaphore method)

Keywords: Java

1. Producers and consumers

Operating system (producer, consumer issues)

 

2. Tube method

(1) Create producer:

public class Productor extends Thread{
    SynContainer synContainer;
    public Productor(SynContainer synContainer){
        this.synContainer=synContainer;
    }
    public void run(){
        for(int i=0;i<10;i++){
            synContainer.push(new Chicken(i));
            System.out.println("Produced"+i+"Chicken");
        }
    }
}

(2) Create consumer:

public class Consume extends Thread {
    SynContainer synContainer;
    public Consume(SynContainer synContainer){
        this.synContainer=synContainer;
    }
    public void run(){
        for(int i=0;i<10;i++){
            System.out.println("Consumption of the"+i+"Chicken");
        }
    }
}

(3) Create product class:

public class Chicken {
    int id;
    public Chicken(int id) {
        this.id=id;
    }
}

(4) Create synchronization code:

public class SynContainer {
    Chicken[] chickens=new Chicken[10];
    //Container counter
    int count=0;
    //Producers produce products
    public synchronized void push(Chicken chicken){
        //If the container is full, you need to wait for consumption
        if(count==chickens.length){
            //Inform consumers of consumption
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //If it is not full, it needs to be dropped into the product
        chickens[count]=chicken;
        count++;
        this.notifyAll();
    }

    public synchronized Chicken pop(){
        //Judge whether it can be consumed
        if(count==0){
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //If you can consume, consume
        count--;
        Chicken chicken=chickens[count];
        //When finished, inform the producer to produce
        this.notifyAll();
        return chicken;
    }
}

Ensure that when there is no product in the container, the product cannot be produced and consumed; when the product in the container is full, the product cannot be produced again

(5) To create a test class:

public class Test {
    public static void main(String[] args) {
        SynContainer synContainer=new SynContainer();
        new Productor(synContainer).start();
        new Consume(synContainer).start();
    }
}

(6) Test:

Produced 0 chickens
 Produced a chicken
 Produced 2 chickens
 Three chickens were produced
 Four chickens were produced
 Five chickens were produced
 Six chickens were produced
 Seven chickens were produced
 Eight chickens were produced
 Nine chickens were produced
 Consumed the 0 th chicken
 First chicken consumed
 Consumption of the second chicken
 Consumption of the third chicken
 Consumption of the fourth chicken
 Consumption of the 5th chicken
 Consumption of the 6th chicken
 Consumption of the 7th chicken
 Consumption of the 8th chicken
 Consumption of the 9th chicken

 

3. Signal lamp method

(1) Create producer:

//Producer: Actor
public class Player extends Thread {
    TV tv;
    public Player(TV tv){
       this.tv=tv;
    }
    public void run(){
        for (int i = 0; i < 20; i++) {
            if(i%2==0){
                this.tv.play("Tom and Jerry");
            }else {
                this.tv.play("Spongebob");
            }
        }
    }
}

(2) Create consumer:

//Consumer: audience
public class Watcher extends Thread {
    TV tv;
    public Watcher(TV tv){
        this.tv=tv;
    }
    public void run(){
        for (int i = 0; i < 20; i++) {
            tv.watch();
        }
    }
}

(3) Write synchronization code:

//Product: Program
public class TV {
    //Actors perform, audience waits
    //Audience watching, actors waiting
    String voice;//A performance
    boolean flag=true;
    //perform
    public synchronized  void play(String voice){
        if(!flag){
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("The actors performed:"+voice);
        //Inform the audience to watch
        this.notifyAll();//awaken
        this.voice=voice;
        this.flag=!this.flag;
    }
    //watch
    public synchronized void watch(){
        if(flag){
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("Watched"+voice);
        //Inform actors to perform
        this.notifyAll();
        this.flag=!this.flag;
    }
}

(4) To create a test class:

//Solved by flag bit
public class Test {
    public static void main(String[] args) {
        TV tv=new TV();
        new Player(tv).start();
        new Watcher(tv).start();
    }
}

(5) Test:

The actor performed: cat and mouse
 Watched the cat and the mouse
 Actors perform: spongebob
 Watch spongebob
 The actor performed: cat and mouse
 Watched the cat and the mouse
 Actors perform: spongebob
 Watch spongebob
 The actor performed: cat and mouse
 Watched the cat and the mouse
 Actors perform: spongebob
 Watch spongebob
 The actor performed: cat and mouse
 Watched the cat and the mouse
 Actors perform: spongebob
 Watch spongebob
 The actor performed: cat and mouse
 Watched the cat and the mouse
 Actors perform: spongebob
 Watch spongebob
 The actor performed: cat and mouse
 Watched the cat and the mouse
 Actors perform: spongebob
 Watch spongebob
 The actor performed: cat and mouse
 Watched the cat and the mouse
 Actors perform: spongebob
 Watch spongebob
 The actor performed: cat and mouse
 Watched the cat and the mouse
 Actors perform: spongebob
 Watch spongebob
 The actor performed: cat and mouse
 Watched the cat and the mouse
 Actors perform: spongebob
 Watch spongebob
 The actor performed: cat and mouse
 Watched the cat and the mouse
 Actors perform: spongebob
 Watch spongebob

(6) The biggest difference between tube method and signal lamp method is to set a flag bit, while tube method is to set a variable according to the value of the variable

Posted by BSkopnik on Mon, 01 Jun 2020 04:48:36 -0700