Java learning log (XII): thread, waiting to wake Case

JavaEE learning log continuously updated ----> must-see! JavaEE learning route (article summary)

Thread State

Given six thread state in the API java.lang.Thread.State this enumeration:

Thread State The occurrence of conditions leading to state
NEW (New) Just create a thread, but did not start. No start method is called.
Runnable (run) In the state of threads can run java virtual machine, may be running their own codes, or may not, depending on the operating system processor.
Blocked (lock blocking) When a thread attempts to acquire a target lock, the lock is held while the object other thread, the thread enters the Blocked state; when the thread holding the lock, the thread will become Runnable state.
Waiting (wait indefinitely) A thread while another thread executes a wait (wake-up) action, the thread enters the Waiting state. After entering this state it is not automatically wake up, have to wait for another thread calls notify or notifyAll method to be able to wake up.
Timed Waiting (timed wait) With waiting state, there are several methods timeout parameters, they will enter the call Timed Waiting state. This state will be maintained until the timeout expires or receives a wake-up notification. Common method with a timeout parameter are Thread.sleep, Object.wait.
Teminated (terminated) Because the run method exits normally and death, or because there is no capture of aborted the run method and death.

Here Insert Picture Description

Waiting and wake-up case (Case Baozi Pu)

And waiting for wakeup: communication threads between the
Object class Method

  • void wait() Causes the current thread to wait for it to be awakened, usually notify or interruption.
  • void notify()Awaken this object's monitor ( object lock single thread) on waiting.

note:

  1. wait和notify方法必须由锁对象调用(必须是同个锁对象
    锁对象–>wait() 锁对象–>notify()
  2. wait和notify方法一般写在同步中

案例:包子铺案例

需求
两大线程:设线程A(包子铺),执行生产包子的动作。线程B(吃货),执行吃包子的操作

共享资源:包子

执行动作:生产一个包子,吃一个包子

分析
包子的状态进行分析
没有包子:吃货线程唤醒包子铺线程—>吃货线程等待—>包子铺线程做包子—>包子铺做好包子—>修改包子的状态—>有包子
有包子:包子铺唤醒吃货线程—>包子铺线程等待—>吃货吃包子—>修改包子的状态—>没有包子
…(循环)

代码实现:

资源类:包子,其中有皮,陷,包子的状态

public class BaoZi {
    String pi;
    String xian;
    //包子状态,初始值为false,没有包子
    boolean flag = false;
}

包子铺类:是一个线程类,线程任务:生产包子

对包子的状态进行判断:
true:有包子
        包子铺线程调用wait等待
false:没有包子
        包子铺线程生产包子
        生产x皮x陷的包子
        生产包子花费3秒
        生产完包子,修改包子状态为true
        包子铺线程唤醒吃货线程,吃包子

注意:

  1. 生产包子和吃包子,只能有一个在执行,需要使用同步技术
  2. 同步技术需要使用锁对象,可以使用包子对象
    在成员位置创建一个包子对象
    使用构造方法为包子变量赋值
public class BaoZiPu implements Runnable {
    //在成员位置创建一个包子对象
    BaoZi bz;
    //使用构造方法为包子变量赋值
    public BaoZiPu(BaoZi bz) {
        this.bz = bz;
    }

    //线程任务:生产包子
    @Override
    public void run() {
        while(true){
/*
            1.生产包子和吃包子,只能有一个在执行,需要使用同步技术
            2.同步技术需要使用锁对象,可以使用包子对象
         */
            synchronized (bz){
                //对包子状态进行判断
                if(bz.flag==true){
                    //true:有包子
                    //            包子铺线程调用wait等待
                    try {
                        bz.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                //包子铺被吃货唤醒之后执行的代码
                //false:没有包子,包子铺线程生产包子
                //生产x皮x陷的包子
                bz.pi = "薄皮";
                bz.xian = "玉米鲜肉";
                System.out.println("包子铺正在生产"+bz.pi+bz.xian+"的包子!");
                //生产包子花费3秒
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //生产完包子,修改包子状态为true
                bz.flag = true;
                //包子铺线程唤醒吃货线程,吃包子
                bz.notify();
                System.out.println("包子铺已经生产好"+bz.pi+bz.xian+"的包子!");
            }
        }
    }
}

吃货类:是一个线程类,线程任务:吃包子

对包子的状态进行判断:
false:没有包子
    吃货线程调用wait等待
true:有包子
    吃货线程开始吃包子
    打印吃x皮x陷的包子
    吃完包子,修改包子的状态为false
    吃货线程唤醒包子铺线程,做包子

注意:

  1. 生产包子和吃包子,只能有一个在执行,需要使用同步技术
  2. 同步技术需要使用锁对象,可以使用包子对象
    在成员位置创建一个包子对象
    使用构造方法为包子变量赋值
public class ChiHuo implements Runnable{
    //在成员位置创建一个包子对象
    BaoZi bz;
    //使用构造方法为包子变量赋值
    public ChiHuo(BaoZi bz) {
        this.bz = bz;
    }

    //线程任务:吃包子
    @Override
    public void run() {
        while (true){
            /*
            1.生产包子和吃包子,只能有一个在执行,需要使用同步技术
            2.同步技术需要使用锁对象,可以使用包子对象
         */
            synchronized (bz){
                //对包子的状态进行判断
                //        false:没有包子
                if (bz.flag==false){
                    //吃货线程调用wait等待
                    try {
                        bz.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            /*
                吃货线程被包子铺线程唤醒之后执行的代码
             */
                //true:有包子,吃货线程开始吃包子
                //打印吃x皮x陷的包子
                System.out.println("吃货正在吃"+bz.pi+bz.xian+"的包子!");
                //吃完包子,修改包子的状态为false
                bz.flag = false;
                //吃货线程唤醒包子铺线程,做包子
                bz.notify();
                System.out.println("吃货已经吃完了"+bz.pi+bz.xian+"的包子!包子铺赶紧生产包子!");
                System.out.println("-----------------------");
            }
        }
    }
}

测试类
创建一个包子对象
创建一个包子铺线程,生产包子
创建一个吃货线程,吃包子

public class Demo01 {
    public static void main(String[] args) {
        //创建一个包子对象
        BaoZi bz = new BaoZi();
        //创建一个包子铺线程,生产包子
        new Thread(new BaoZiPu(bz)).start();
        //创建一个吃货线程,吃包子
        new Thread(new ChiHuo(bz)).start();
    }
}

运行结果:

包子铺正在生产薄皮玉米鲜肉的包子!
包子铺已经生产好薄皮玉米鲜肉的包子!
吃货正在吃薄皮玉米鲜肉的包子!
吃货已经吃完了薄皮玉米鲜肉的包子!包子铺赶紧生产包子!
-----------------------
包子铺正在生产薄皮玉米鲜肉的包子!
包子铺已经生产好薄皮玉米鲜肉的包子!
吃货正在吃薄皮玉米鲜肉的包子!
吃货已经吃完了薄皮玉米鲜肉的包子!包子铺赶紧生产包子!
-----------------------
...
Published 16 original articles · won praise 17 · views 1834

Guess you like

Origin blog.csdn.net/Sakuraaaaaaa/article/details/104234964