JAVA wait for the wake-up mechanism to achieve the case_buy buns (multi-threaded, synchronized)

principle

Waiting to wake up

The wait for wake-up mechanism is used to solve the problem of communication between threads. The meanings of the three methods used are as follows:

  1. wait: The thread is no longer active, no longer participates in scheduling, and enters the wait set. Therefore, it will not waste CPU resources and will not compete for locks. The thread status at this time is WAITING. It also has to wait for other threads to perform a special action , that is, " notify " the threads waiting on this object are released from the wait set and re-enter the ready queue.
  2. notify: select a thread in the wait set of the notified object to release; for example, after a restaurant has a free seat, the customer who has been waiting for the longest meal will be seated first.
  3. notifyAll: release all threads on the wait set of the notified object.

Note:
Even if only a waiting thread is notified, the notified thread cannot resume execution immediately, because the place where it was interrupted was in the synchronization block, and it does not hold the lock at this moment, so she needs to try to acquire the lock again ( It is likely to face competition from other threads), and only after success can the execution resume at the place after the original call to the wait method.

The summary is as follows:
if the lock can be acquired, the thread changes from the WAITING state to the RUNNABLE state;
otherwise, from the wait set and enters the entry set, the thread changes from the WAITING state to the BLOCKED state again

The details that need to be paid attention to when calling wait and notify methods

  1. The wait method and notify method must be called by the same lock object. Because: the corresponding lock object can wake up the thread after the wait method called by the same lock object through notify.
  2. The wait method and notify method are methods of the Object class. Because: the lock object can be any object, and the class of any object inherits the Object class.
  3. The wait method and notify method must be used in synchronous code blocks or synchronous functions. Because: these two methods must be called through the lock object.

analysis

Baozipu threads produce steamed buns, and eat goods threads consume steamed buns. When there are no buns (the bun status is false), the food-eater thread waits, and the Baozipu thread produces the buns (that is, the bun status is true), and informs the food-eater thread (the waiting state of the food is released), because there are already buns, then the bunpu thread Enter the waiting state. Next, whether the food-eating thread can execute further depends on the acquisition of the lock. If the foodie obtains the lock, it executes the action of eating the steamed buns, the steamed buns are finished (the steamed buns status is false), and the Baozipu thread is notified (releasing the waiting state of the steamed buns shop), and the foodie thread enters the wait. Whether the Baozipu thread can execute further depends on the acquisition of the lock.

Code

Attributes of Baozi_Baozi Class

public class Baozi {
    
    
    private String pier;
    private String xianer;
    private boolean isBaozi = false;

    public Baozi(String pier, String xianer, boolean isBaozi) {
    
    
        this.pier = pier;
        this.xianer = xianer;
        this.isBaozi = isBaozi;
    }

    public Baozi() {
    
    
    }

    public String getPier() {
    
    
        return pier;
    }

    public void setPier(String pier) {
    
    
        this.pier = pier;
    }

    public String getXianer() {
    
    
        return xianer;
    }

    public void setXianer(String xianer) {
    
    
        this.xianer = xianer;
    }

    public boolean isBaozi() {
    
    
        return isBaozi;
    }

    public void setBaozi(boolean baozi) {
    
    
        isBaozi = baozi;
    }
}

Producer class _Produce class

public class Produce extends Thread{
    
    
    Baozi bz ;
    public Produce(Baozi bz){
    
    
        this.bz=bz;
    }
    @Override
    public void run() {
    
    
        int count = 0;
        while (true){
    
    
            synchronized (bz){
    
    
                if(bz.isBaozi()==true) {
    
    
                    try {
    
    
                        bz.wait();
                    } catch (InterruptedException e) {
    
    
                        e.printStackTrace();
                    }
                }
                System.out.println("老板正在做包子");
                if(count%2 == 0 ){
    
    
                    bz.setPier("厚皮儿");
                    bz.setXianer("三鲜馅儿");
                }else{
    
    
                    bz.setPier("薄皮儿");
                    bz.setXianer("韭菜馅儿");
                }
                try {
    
    
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
    
    
                    e.printStackTrace();
                }
                System.out.println(bz.getXianer()+bz.getPier()+"的包子做好了");
                count++;
                bz.setBaozi(true);
                bz.notify();
            }
 }}}

Consumer class_Eat class

public class Eat extends Thread{
    
    
    Baozi bEat ;
    public Eat(Baozi bEat){
    
    
        this.bEat=bEat;
    }
    @Override
    public void run() {
    
    
        while (true){
    
    
            synchronized (bEat){
    
    
                if(bEat.isBaozi()==false) {
    
    
                    try {
    
    
                        bEat.wait();
                    } catch (InterruptedException e) {
    
    
                        e.printStackTrace();
                    }
                }
                System.out.println("吃货吃包子");
                System.out.println("吃货吃完包子");
                bEat.setBaozi(false);
                System.out.println("===========================================");
                System.out.println();
                bEat.notify();
            }
        }
    }
}

Test implementation class

public class main {
    
    
    public static void main(String[] args) {
    
    
        Baozi bz =new Baozi();
        Produce p = new Produce(bz);
        Eat e = new Eat(bz);
        p.start();
        e.start();
    }
}

result

Cycle as follows:

老板正在做包子
三鲜馅儿厚皮儿的包子做好了
吃货吃包子
吃货吃完包子
===========================================

老板正在做包子
韭菜馅儿薄皮儿的包子做好了
吃货吃包子
吃货吃完包子
===========================================

Guess you like

Origin blog.csdn.net/TOPic666/article/details/107908430